简体   繁体   中英

Asynchronous Execution Order in JavaScript

I don't understand why following execution output is 1 3 4 2 6 5 ;

 Promise.resolve().then(() => console.log(2)); (async() => console.log(await 6))(); console.log(1); (async() => await console.log(3))(); Promise.resolve().then(() => console.log(5)); console.log(4);

Here's how your code executes:

  1. Promise.resolve() creates a resolved promise which puts () => console.log(2) in the micro-task queue

    queue: [ () => console.log(2) ]
  2. The IIFE executes in which you have await 6 . Awaiting 6 is similar to wrapping it in Promise.resolve(6) and then awaiting it: await Promise.resolve(6) .

    When the operand of await is not a promise, await creates a native promise and uses the operand's value to resolve that promise

     queue: [ resolve(6), () => console.log(2) ]
  3. 1 is logged on the console

    queue: [ resolve(6), () => console.log(2) ] console output: 1
  4. Second IIFE executes where you have await console.log(3) . This is like await undefined because console.log(3) will execute, 3 will be logged on the console and the return value of console.log , ie undefined will be awaited.

    In short, you are awaiting undefined .

     queue: [ resolve(undefined), resolve(6), () => console.log(2) ] console output: 1 3
  5. Promise.resolve() creates a resolved promise which puts () => console.log(5) in the micro-task queue

    queue: [ () => console.log(5), resolve(undefined), resolve(6), () => console.log(2) ] console output: 1 3
  6. 4 is logged on the console

    queue: [ () => console.log(5), resolve(undefined), resolve(6), () => console.log(2) ] console output: 1 3 4
  7. Script execution end

  8. Event loop will now begin processing the micro-task queue

  9. 2 will be logged on the console because it was queued first

    queue: [ () => console.log(5), resolve(undefined), resolve(6) ] console output: 1 3 4 2
  10. await 6 resolves with the value 6 which is then passed to console.log . As a result 6 is logged on the console

    queue: [ () => console.log(5), resolve(undefined) ] console output: 1 3 4 2 6
  11. Promise created as a result of await console.log(3) resolves with the value of undefined

    queue: [ () => console.log(5) ] console output: 1 3 4 2 6
  12. 5 is logged on the console

    queue: [ ] console output: 1 3 4 2 6 5
  13. Done.


Note: Your code shouldn't rely on the timing and order in which different unrelated promises are resolved.

There are two sequences here: 1 3 4 and 2 6 5 . The first is produced on the first tick (before any promises have resolved, and the second on the second tick (after promise resolution).

(async() => await console.log(3))(); writes 3 to the log before the await, so the 3 appears before any promises resolve, and between 1 and 4 because of the order of the statements. (Note that the await in this line resolves to undefined , because console.log doesn't return anything).

For the sequence 2 6 5 , all of the console logs come after a promise resolves (or, equivalently, an await statement), and they're in natural order otherwise.

1 is printed first because of order of execution. 3 is printed as code is executed because console.log() is not an asynchronous operation. Does not matter if you put await in front of it. 4 is again printed because of order of execution.

Now, rest of the order of execution is due to asynchronous operations. The 3 statements are printed in an asynchronous manner after the above 3 statements are executed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM