When you think about Promise execution order, what do you think?

“It’s the same old macro task, micro task, and event loop.”

Let’s start with two questions and see if we can get them right, and if you’re too lazy to copy and run them in your browser, skip to the end of the article and see 👀

/ / case
new Promise((resolve, reject) = > {  
  resolve(1);  
  Promise.resolve().then(() = >{  
        console.log(2);  
  })  
}).then((t) = >{console.log(t)});  
console.log(3);
Copy the code
/ / the second case
new Promise((resolve, reject) = >{  
    Promise.resolve().then(() = >{  
        resolve(1);  
        Promise.resolve().then(() = >{console.log(2)})  
    })  
}).then((value) = >{console.log(value)});  
console.log(3);
Copy the code

How, and you expected consistent, if consistent, which you can go, this article is not suitable for you!

If you’re scratching your head, keep reading

Execution order

Let me start with an idea

The.then() method is synchronous, and the callback is asynchronous

Case 1 Execution sequence

1, the new Promise (…).

The new Promise is the synchronization code, and the callback is executed first

2, resolve (1)

At this time, the outermost Promise state changes from pedding state to resolve.

Note that the outermost Promise has not registered any callbackssince the outermost then() has not been executed yet, so (t) => console.log(t) will not be placed in Microtask

3, Promise. Resolve (). Then (…).

.then() puts the callback inside the Microtask to see the current state of the execution stack

JS Stack: []
Microtask: [() => console.log(2)]
Copy the code

4. ((t) = > {the console. The log (t)})

The state of the then method is resolved. Therefore, the callback inside the THEN is pushed into the Microtask, and the state of the execution stack is now resolved

JS Stack: []
Microtask: [() = > console.log(2), (1) = > console.log(1)]
Copy the code

5, the console. The log (3)

This must be synchronized, and the JS Stack is empty at this point, so it immediately presses the Stack and executes, print 3

The state of the execution stack

JS Stack: []
Microtask: [() = > console.log(2), (1) = > console.log(1)]
Copy the code

() => console.log(2) is pushed into the JS Stack and executed, and () => conosle.log(1) is pushed into the JS Stack and executed

So case one prints 3, 2, 1

Execution sequence of Case 2

1, the new Promise (…).

Needless to say, synchronous execution, directly look inside the callback

2, Promise. Resolve (). Then (…).

.thenIs synchronous, but the callback inside is asynchronous, so the callback entersMicrotask, the state of the execution stack

JS Stack: []
Microtask: [ () = > {resolve(1); Promise.resolve().then(....)} ]
Copy the code

3,. (…).

To the outermost layerPromisethethenMethod, pressure the callback intoMicrotask, the state of the execution stack

JS Stack: []
Microtask: [ () = > {resolve(1); Promise.resolve().then(....) },(value) = > console.log(value) ]
Copy the code

At this point, there are two tasks queued in the microtask queue. The first is the level-2 promise.then callback, and the second is the level-1 promise.then callback

4, the console. The log (3)

Synchronize, execute now, print 3, the state of the execution stack at this point

JS Stack: []
Microtask: [() = > {resolve(1); Promise.resolve().then(....) },(value) = > console.log(value)]
Copy the code

5. Elevate the level2 promise-Callback from the Micotask to the JS Stack

The state of the execution stack

JS Stack: [() = > {resolve(1); Promise.resolve().then(() = > console.log(2))}]
Microtask: [(value) = > console.log(value)]]
Copy the code

When the execution reaches resolve(1), the Promise state of the first layer changes from pedding to Resolve

Next, promise.resolve ().then(() => console.log(2)} is executed, and the callbacks in the THEN are pushed into the Microtask

JS Stack: []
Microtask: [ (1) = > console.log(1), () = > console.log(2)]Copy the code

6. Elevate the level-1 promise-Callback from the Micotask to the JS Stack

The state of the execution stack

JS Stack: [ (1) = > console.log(1)]Microtask: [ () = > console.log(2)]Copy the code

After the command is executed, 1 is displayed

7. Promote layer 3 promise-Callback from the Micotask to the JS Stack

At this point the stack state is executed

JS Stack: [ () = > console.log(2)]Microtask: []
Copy the code

2 is displayed after the command is executed

To sum up, the printed result of case 2 is 3, 1, 2

The answer

Case 1 print: 3 2 1

Case 2 print: 3 1 2

reference

The execution order of jS-promise