Skip to main content
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Adam Tuttle
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Adam Tuttle ( @adamtuttle )

The ES6 Promise Constructor And Its Executor Function Are Invoked Synchronously

By 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.

Want to use code from this post? Check out the license.

Reader Comments

15,674 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).

1 Comments

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?

15,674 Comments

@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!

4 Comments

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.

15,674 Comments

@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).

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel