-
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 -
Deferred
is 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
abort
in 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 rejected
with 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;
};