0

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);

5
  • 2
    Related: stackoverflow.com/questions/68784426/promise-chain-then-catch Commented Aug 22, 2021 at 15:10
  • Thanks! This thread is related but not helpful enough. Commented Aug 22, 2021 at 15:12
  • 4
    Find it hard to believe you absorbed all of it's content and other links in two minutes Commented Aug 22, 2021 at 15:14
  • 1
    What output do you expect? Commented Aug 22, 2021 at 15:18
  • I just found this thread is about promise chain at first, I will check it again. Commented Aug 22, 2021 at 15:33

3 Answers 3

2

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, i.e. 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.

Sign up to request clarification or add additional context in comments.

1 Comment

The steps you demonstrated is perfect! I think this resolved my problem.
0

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.

2 Comments

Does the await of 3 block the codes below?
@young-trigold no, it does not.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.