Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Cameron Childress
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Cameron Childress@cameronc )

The ES6 Promise Constructor And Its Executor Function Are Invoked Synchronously

By Ben Nadel on

This is primarily a note-to-self; but, I just wanted to codify the fact that the ES6 Promise construtor - and the executor function that you pass to it - are invoked synchronously in your code. The only reason that this is worth mentioning at all is because everything else about Promises are asynchronous. So, it's not entirely obvious that your executor function wouldn't also be invoked asynchronously. But, the fact that it is synchronous means that you can make strong assertions about the order of operations in your control flow.

To see this in action, all we have to do is log some messages around the Promise constructor and the invocation of our executor function:

  • console.log( "Start." );
  •  
  • // Check to see that Promise constructor is executed synchronously.
  • var promise = new Promise(
  • function( resolve, reject ) {
  •  
  • console.log( "In Promise constructor." );
  •  
  • resolve( "Future value." );
  •  
  • }
  • );
  •  
  • // Check to see that Promise resolution handlers are invoked asynchronously.
  • promise.then(
  • function( result ) {
  •  
  • console.log( "Promise resolution:", result );
  •  
  • }
  • );
  •  
  • console.log( "End." );

As you can see, we're logging messages to the console in and around the Promise constructor. And, when we run this code in Node.js, we get the following output:


 
 
 

 
 The promise constructor and its executor function are invoked synchronously. 
 
 
 

As you can see, the log statement in our Promise constructor and executor function is invoked synchronously, falling in between the "Start" and "End" log statements. And, of course, our Promise resolution handler is invoked asynchronously as we expect it to be.

This may seem like an unnecessary investigation; but, having a solid mental model for Promise execution is an important part of understanding control flow in JavaScript and Node.js. It means that we can make strong assertions about the order of operations in our code; and, most importantly, about possible race conditions in the JavaScript event loop.



Looking For A New Job?

Ooops, there are no jobs. Post one now for only $29 and own this real estate!

100% of job board revenue is donated to Kiva. Loans that change livesFind out more »

Reader Comments

@Ben,

Good link - Nolan is the man. I've been really digging the PouchDB library this year -- hoping to build an offline-first app with it (when I can be better about actually concentrating).

Reply to this Comment

Thanks for clarifying the solid mental model, I think that's the primary difference between promises and observables (RxJS).

BTW, I really to read your code, can you please share linting configuration you have set up?

Reply to this Comment

@Rumen,

I appreciate your comment - but I don't have a linter :D This is just the way I normally code. And, I'm thrilled that you like it - many people really do not like the way that I format my code. Much thanks!

Reply to this Comment

Probably best to point out that the resolve() is actually happening synchronously along with everything else, it's the then() that receives it, that is being handled outside of the main execution.

Reply to this Comment

@Blade,

Ah, interesting. I am not sure how reduce is implemented under-the-covers; but, to be sure, all function invocations are always synchronous (though they may lead to asynchronous behavior, as you are saying, with the subsequent .then() call).

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.