By qnimate


2015-04-30 08:48:41 8 Comments

Suppose I have this code

function y(resolve, reject)
{
  console.log("Result");
  resolve();
}  

var promise = new Promise(y);

What I want to know is whether the function y will be executed asynchronously or not.

2 comments

@Dan Pantry 2015-04-30 08:55:58

It depends on the implementation of the promise. If we check the spec. You can find the final spec here - since this answer was originally written, it has been finalized.

Here is the relevant excerpt (you can find the original source here)

  1. Let completion be Call(executor, undefined, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
  2. If completion is an abrupt completion, then
    • Let status be Call(resolvingFunctions.[[Reject]], undefined, «completion.[[value]]»).
    • ReturnIfAbrupt(status).

The ES6 standard indicates that the fulfillment of a promise is always asynchronous (See section 25.4.5.3, Promise.prototype.then and accompanying section 25.4.5.3.1, PerformPromiseThen). I have placed the relevant material below.

PerformPromiseThen

  1. Else if the value of promise's [[PromiseState]] internal slot is "fulfilled",
    • Let value be the value of promise's [[PromiseResult]] internal slot.
    • Perform EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction, value»).
  2. Else if the value of promise's [[PromiseState]] internal slot is "rejected",
    • Let reason be the value of promise's [[PromiseResult]] internal slot.
    • Perform EnqueueJob("PromiseJobs", PromiseReactionJob, «rejectReaction, reason»).

TLDR: the function passed to the promise is executed synchronously, but subsequent then calls are always executed asynchronously.

@slebetman 2015-04-30 09:01:35

The mozilla version is easier to read though, as the official ones are in PDF

@Dan Pantry 2015-04-30 09:02:10

I'll stick it in just in case, there might be some discrepancies especially to future readers (though the spec is on the final draft so it is unlikely)

@slebetman 2015-04-30 09:07:57

In the future, this answer will be outdated and irrelevant (I should know, I have lots of js answers go that way from way back) :D

@Dan Pantry 2015-04-30 09:08:30

Here's to hoping it's not.. :P I've put the final draft spec in, there was one discrepancy but it was fairly minor.

@Benjamin Gruenbaum 2015-04-30 09:54:39

There is no official spec since it's a draft. Trust me this won't change.

@Dan Pantry 2015-04-30 09:55:34

thanks for clarification, will update - this is probably the first time I've referred to a spec for behaviour.

@Dan Pantry 2015-06-26 09:44:49

Thank you @BenjaminGruenbaum for updating with the finalized specification :)

@Benjamin Gruenbaum 2015-06-26 09:50:44

Sure thing, glad I could help

@Joe Lapp 2016-02-26 14:19:26

I'm not seeing the answer in the spec. "Let completion be Call(..." is not a call of the executor but a declaration of the meaning of "completion." I can't seem to find an official answer about when the executor function (as in new Promise(executor)) is called. Is it always called immediately upon promise creation? Are there circumstances where it is only called upon calling then()?

@Dan Pantry 2016-02-26 14:31:22

@JoeLapp As per the answer below this, the executor will always be executed synchronously, but the callback provided to then will be executed asynchronously

@Joe Lapp 2016-02-26 18:49:11

@DanPantry In order for code within multiple promises to run asynchronously, the executor function of each promise would have to be called in succession synchronously, so that there's no waiting between the initiation of successive promises. Where is the official statement about when the executor function gets called? Is the executor function required to be called (synchronously) with the creation of a promise? I suspect that a clear answer won't use the words "synchronous" or "asynchronous" and will just tell exactly where the executor is called.

@Joe Lapp 2016-02-26 18:56:10

I just checked the RSVP library. It calls the executor immediately with the creation of a new Promise. I'm just wondering whether that's required (by some specification), or whether that can be deferred. The constructor calls initializePromise(), found here: github.com/tildeio/rsvp.js/blob/master/lib/rsvp/-internal.js

@Benjamin Gruenbaum 2015-04-30 09:55:23

The other answer proves this, but let me talk about the reasoning:

Promise constructor

The promise constructor callback (as specified either in the ES6 spec or the constructor spec libraries implement) will always be executed synchronously - this is in order to extract a deferred (older form of promise construction) out of it in case you need to have access to the resolve callback:

var r;
var p new Promise(function(resolve, reject){
    r = resolve;
});
// use r here, for example
arr.push(r);

then callbacks

then will always be executed asynchronously, virtually all mainstream promise implementations (Native, bluebird, $q, Q, when, rsvp, promise, jQuery (as of 3.0) etc) as well as native promises implement (or implement a superset of, with more constraints) Promises/A+.

This is exactly the reason that Promises/A+ was created out of Promises/A. Asynchronous guarantees will be preserved and Zalgo won't be released. (Also see this post).

The fact this happens (asynchronous guarantee) is completely intentional and actively prevents race conditions. Code in- and outside of then will always execute in the same order.

Here is the relevant quote:

onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].

Related Questions

Sponsored Content

26 Answered Questions

[SOLVED] How can I pass a parameter to a setTimeout() callback?

33 Answered Questions

[SOLVED] How can I upload files asynchronously?

36 Answered Questions

[SOLVED] How do I return the response from an asynchronous call?

25 Answered Questions

17 Answered Questions

10 Answered Questions

20 Answered Questions

[SOLVED] How do I convert an existing callback API to promises?

11 Answered Questions

[SOLVED] How to measure execution time of javascript code with callbacks

10 Answered Questions

[SOLVED] AngularJS : Initialize service with asynchronous data

2 Answered Questions

[SOLVED] Why does javascript ES6 Promises continue execution after a resolve?

Sponsored Content