In depth promise (2) — promise of attack

Time:2021-3-7

There’s a question about promise on twitter. What’s the order of execution? See the figure below:
We assume that dosomething takes 1 s and dosomething else takes 1.5 s

function doSomething() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('something')
    }, 1000)
  })
}

function doSomethingElse() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('somethingElse')
    }, 1500)
  })
}
  1. In the first case:

    console.time('case 1')
    doSomething().then(() => {

    return doSomethingElse()

    }).then(function finalHandler(res) {

    console.log(res)
    console.timeEnd(‘case 1’)

    })
    

Print out:

somethingElse
case 1: 2509ms

The execution sequence is as follows:

doSomething()
|----------|
           doSomethingElse()
           |---------------|
                           finalHandler(somethingElse)
                           |->

Explanation: normal promise usage.

  1. Second case:

    console.time('case 2')
    doSomething().then(function () {
      doSomethingElse()
    }).then(function finalHandler(res) {
      console.log(res)
      console.timeEnd('case 2')
    })
    

Print out:

undefined
case 2: 1009ms

The execution sequence is as follows:

doSomething()
|----------|
           doSomethingElse()
           |---------------|
           finalHandler(undefined)
           |->

Explanation: because return is not used, dosomething else is executed asynchronously after dosomething is executed.

  1. Third case:

    console.time('case 3')
    doSomething().then(doSomethingElse())
      .then(function finalHandler(res) {
        console.log(res)
        console.timeEnd('case 3')
      })
    

Print out:

something
case 3: 1008ms

The execution sequence is as follows:

doSomething()
|----------|
doSomethingElse()
|---------------|
           finalHandler(something)
           |->

Explanation: the above code is equivalent to:

console.time('case 3')
var doSomethingPromise = doSomething()
var doSomethingElsePromise = doSomethingElse()
doSomethingPromise.then(doSomethingElsePromise)
  .then(function finalHandler(res) {
    console.log(res)
    console.timeEnd('case 3')
  })

And we know that then needs to accept a function, otherwise the value will be penetrated, so print something.

  1. Fourth case:

    console.time('case 4')
    doSomething().then(doSomethingElse)
      .then(function finalHandler(res) {
        console.log(res)
        console.timeEnd('case 4')
      })
    

Print out:

somethingElse
case 4: 2513ms

The execution sequence is as follows:

doSomething()
|----------|
           doSomethingElse(something)
           |---------------|
                           finalHandler(somethingElse)
                           |->

Explanation: dosomethingelse is passed in as the then parameter. It does not cause value penetration and returns a promise, so it will be executed sequentially.