Reputation: 151076
I can find some blog posts stating that JavaScript ES6's promise is Promise/A+, but the official ES6 specs doesn't mention it, and MDN has a link to Promise/A+ at the very bottom, but didn't state that ES6 JavaScript's promise is exactly the same as Promise/A+.
Sometimes it is stated as "ES6 promise is based on Promise/A+", but are they exactly the same? ( is it mentioned in official docs, such as from ECMA or MDN?)
Upvotes: 7
Views: 566
Reputation: 350477
The EcmaScript Promise
constructor produces promises that are fully Promises/A+ compliant. They obey all the rules in the Promises/A+ specification.
The inverse is not true. A Promises/A+ compliant implementation of promises is not necessarily compliant with the EcmaScript specification, even when we focus only on the then
method, which is what the Promises/A+ specification really is about (for instance, the latter does not specify how promises should be created).
Some examples:
Section 3.1 of the Promises/A+ specification gives some details about how implementations could schedule the asynchronous jobs that emerge from promises:
This can be implemented with either a “macro-task” mechanism such as
setTimeout
orsetImmediate
, or with a “micro-task” mechanism such asMutationObserver
orprocess.nextTick
. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called.
But the EcmaScript specification is more specific on this. It defines the PromiseJobs queue exclusively used for this purpose, and so an implementation that would instead use the same queue as the one used by setTimeout
would violate this requirement.
Although the Promises/A+ specification requires an order of execution of the callbacks that are provided to multiple then
methods on the same promise (see 2.6.6), it does not set an order of execution when it concerns different promises.
To illustrate:
let promiseA = Promise.resolve(1);
let promiseB = Promise.resolve(2);
promiseA.then(console.log);
promiseB.then(console.log);
Here the output is 1 and 2, but a Promises/A+ compliant implementation could (for some odd reason) bring about the reverse output. That would not be compliant with the EcmaScript specification, but still with the Promises/A+ specification.
Yet another example can be found in Why is a new promise resolved earlier with p.then(resolve) than with resolve(p)?
Upvotes: 0
Reputation: 1074666
They aren't identical, but JavaScript's promises are fully compliant with the Promises/A+ specification.
Promises/A+ is intentionally minimalist. JavaScript's promises have utility features that aren't covered by the Promises/A+ spec (such as catch
and finally
). Those are implemented using only features covered by Promises/A+, though. For instance, catch
and finally
are implemented via calls to then
. (Literally, not just conceptually.) If you look at the specification for catch
for example, it says catch
is literally this:
class Promise {
// ...
catch(onRejected) {
return this.then(undefined, onRejected);
}
// ...
}
(finally
is a bit more complex, but it too ends up calling then
and returning the promise it creates.)
JavaScript's promises also have the occasional optimization that only works if a native promise (instead of a promise from a third-party library) is used, but again, they're fully compliant with Promises/A+.
Upvotes: 7