-
Promise is about spec and implementations(then/promise, q, bluebird)
-
Beside enabling async, Promise is another way to make function calling look nicer, kinda like pipe, instead of
f(g(x)), dox -> f -> g -
promise.then(undefined, onRejected)is exactly the same aspromise.catch(onRejected). -
Build your own way of handling return value(like return a reason code) when promise chain is complicated. For example, if the promise chain continues after
catch(), you need to handle return value from both previousthen()s andcatch()s -
Instead of
new Promise(), usePromise.resolve()to start promise chain -
Deferredis just a wrapper ofpromise, itresolve()orreject()wherever you need in your code, while promiseresolve()orreject()inside callbacks -
Promise chain works because each
.then()or.catch()return a new promise -
To use promise in IE8 and below, replace
promise.catch()withpromise['catch']() -
In
Promise.race, other promises won’t stop or abort when first promise get fullfilled -
There is NO
abortin ES6 Promise, while some libraries(bluebird) DO implementabort. Of course, you can implement it with lines of code like this gist -
ES6 Promise comes from Promise/A+, which comes from CommonJS group(famous for CommonJS module spec)
-
When unhandled rejection happens in promise callbacks, all you see is something like
Promise rejectedwith no stack info. -
Export promise, reference
function defer() { var res, rej; var promise = new Promise((resolve, reject) => { res = resolve; rej = reject; }); promise.resolve = res; promise.reject = rej; return promise; } this.treeBuilt = defer(); // Many, many lines below… this.treeBuilt.resolve(); - There is no elegant way to tell if a promise is resolved
- given you have access to the promise, of course you can do:
let isResolved = false; p.then(function() { isResolved = true; }); - if you don’t have access to it:
const marker = {} async function isResolved(p) { return (await Promise.race([p, marker])) != marker }
- given you have access to the promise, of course you can do:
- Minimum implementation
function Promise() {
this._callbacks = [];
this._errCallbacks = [];
this._resolved = 0;
this._result = null;
}
Promise.prototype.resolve = function (err, res) {
if (!err) {
this._resolved = 1;
this._result = res;
for (var i = 0; i < this._callbacks.length; ++i) {
this._callbacks[i](res);
}
} else {
this._resolved = 2;
this._result = err;
for (var iE = 0; iE < this._errCallbacks.length; ++iE) {
this._errCallbacks[iE](res);
}
}
this._callbacks = [];
this._errCallbacks = [];
};
Promise.prototype.then = function (cb, errCb) {
// result
if (this._resolved === 1) {
if (cb) {
cb(this._result);
}
return;
// error
} else if (this._resolved === 2) {
if (errCb) {
errCb(this._result);
}
return;
}
if (cb) {
this._callbacks[this._callbacks.length] = cb;
}
if (errCb) {
this._errCallbacks[this._errCallbacks.length] = errCb;
}
return this;
};