What is the standard behaviour if a ES6 promise is rejected / resolved multiple times?
The following code was only resolved once in Google Chrome
, is this the standard behaviour in all browsers?
new Promise(function(e) {
$('#button').click(function(){
resolve();
});
});
I have seen a promise polyfill throwing an exception on trying to resolve an already resolved promise. Does the specification for es6-promise specify this, or isn't the polyfill standard compliant?
Update
Sorry, I just realized that it is not a polyfill, but just a minimal implementation of a Promise (non standard).
Promise resolve() method: If the value is a promise then promise is returned. If the value has a “then” attached to the promise, then the returned promise will follow that “then” to till the final state. The promise fulfilled with its value will be returned.
A Promise executor should call only one resolve or one reject . Once one state is changed (pending => fulfilled or pending => rejected), that's all. Any further calls to resolve or reject will be ignored.
Show activity on this post. Since promises can only resolve once (to either fulfilled or rejected), the first resolution wins and any further calls will be ignored. From the docs: In all cases where a promise is resolved (i.e. either fulfilled or rejected), the resolution is permanent and cannot be reset.
The Promise. resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise. resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.
A promise cannot be resolved or settled more than once. Once the promise is resolved, fulfilled, or rejected, further calls to resolve or settle it are ignored. (If those terms are unfamiliar or only vaguely-familiar, I've written about promise terminology on my blog.) No error is raised.
I have seen a promise polyfill throwing an exception on trying to resolve an already resolved promise. Does the specification for es6-promise specify this...?
No. This is covered in Promise Resolve Functions, which says what they do. Here are the first few steps:
When a promise resolve function is called with argument resolution, the following steps are taken:
- Let F be the active function object.
- Assert: F has a [[Promise]] internal slot whose value is an Object.
- Let promise be F.[[Promise]].
- Let alreadyResolved be F.[[AlreadyResolved]].
- If alreadyResolved.[[Value]] is true, return undefined.
(my emphasis)
There are folks who argue that attempting to resolve or settle a promise that is already resolved or settled should be an error. Since that didn't make it into the spec for ES2015, it probably will never be added, as it wouldn't be backward-compatible with existing code.
According to the ECMAScript 2015 Language Spec
Promise Objects
A Promise is an object that is used as a placeholder for the eventual results of a deferred (and possibly asynchronous) computation.
Any Promise object is in one of three mutually exclusive states: fulfilled, rejected, and pending: A promise p is fulfilled if p.then(f, r) will immediately enqueue a Job to call the function f. A promise p is rejected if p.then(f, r) will immediately enqueue a Job to call the function r. A promise is pending if it is neither fulfilled nor rejected. A promise is said to be settled if it is not pending, i.e. if it is either fulfilled or rejected.
A promise is resolved if it is settled or if it has been “locked in” to match the state of another promise. Attempting to resolve or reject a resolved promise has no effect. A promise is unresolved if it is not resolved. An unresolved promise is always in the pending state. A resolved promise may be pending, fulfilled or rejected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With