2

I am confused of the output of this code. The output is 4 3 2 1

How do I understand the flow?

new Promise(resolve => { resolve(1); Promise.resolve().then(() => console.log(2)); console.log(4); }).then( t => console.log(t) ); console.log(3); 
4
  • 2
    synchronous code remains synchronous, asynchronous code remains asynchronous - you can see the execution sequence of the console.log's from the output Commented Feb 14, 2018 at 8:19
  • 1, 2, 3 (up to .then), 4, 5 (up to .then) 6,3 (code inside .then), 5 (code inside .then) - or, see jsfiddle.net/gzy6ncz3 Commented Feb 14, 2018 at 8:23
  • What output did you expect? There are links to a video and some documentation in this answer that could help. Commented Feb 14, 2018 at 9:16
  • Thinking of resolve() doing something like a setTimeout(later, 0) where later is then function registered using then could be a good way to reason about what is happening no? I mean that is what it meas to say this is asynchronous. It gets pushed to the event-loop right? Commented Feb 14, 2018 at 12:50

2 Answers 2

3

I think the key understandings are

  • a new Promise callback is always invoked synchronously (during the call)
  • a then callback is always invoked asynchronously (later)

So the individual synchronous steps here are, in order:

new Promise(resolve => { // begins creating a promise resolve(1); // fulfills the promise Promise.resolve() // creates a promise .then(…); // registers a callback console.log(4); // logs the first line }) // finishes the promise creation .then(…); // registers a callback console.log(3); // logs the second line 

When the callbacks are registered, then checks whether the promise is already settled, and this is the case here (for both promises), it immediately schedules them by putting them on a queue. In theory this queue defines a specific order, in practice you should ignore that (i.e. things scheduled at the same time can happen in any order). If you want a specific order, always make an explicit promise chain instead of relying on internal queuing.

So here we have two scheduled items:

() => // the first item is called with undefined (result of `Promise.resolve()`) console.log(2) // logs the third line t => // the second item is called with 1 (from the `resolve(1)` call) console.log(t) // logs the fourth line 
Sign up to request clarification or add additional context in comments.

Comments

0

This depends on the way Promise is implemented. Promises/A+ specification needs the function registered using then, say later, to be done asynchronously.

So, thinking of resolve(1) doing something like the below can help you reason about the asynchronous flow explained in the above comments:

  1. Set the promise's value to 1
  2. Register a setTimeout(later, 0), where later is the function registered by then

setTimeout is the key, it just pushes it to the event-loop instead of doing it right away because spec says so.

So in,

new Promise(resolve => { resolve(1); Promise.resolve().then(() => console.log(2)); console.log(4); }).then( t => console.log(t) ); console.log(3); console.log(2) // gets queued console.log(4) // gets executed console.log(3) // gets executed console.log(1) // gets queued 

You can see a related questions here: Why do Promise libraries use event loops?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.