Promise库
标准
https://promisesaplus.com/
An open standard for sound, interoperable JavaScript promises—by implementers, for implementers.
A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its
thenmethod, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.
Terminology
- “promise” is an object or function with a
thenmethod whose behavior conforms to this specification.- “thenable” is an object or function that defines a
thenmethod.- “value” is any legal JavaScript value (including
undefined, a thenable, or a promise).- “exception” is a value that is thrown using the
throwstatement.- “reason” is a value that indicates why a promise was rejected.
Requirements
Promise States
A promise must be in one of three states: pending, fulfilled, or rejected.
- When pending, a promise:
- may transition to either the fulfilled or rejected state.
- When fulfilled, a promise:
- must not transition to any other state.
- must have a value, which must not change.
- When rejected, a promise:
- must not transition to any other state.
- must have a reason, which must not change.
Here, “must not change” means immutable identity (i.e.
===), but does not imply deep immutability.The
thenMethodA promise must provide a
thenmethod to access its current or eventual value or reason.A promise’s
thenmethod accepts two arguments:promise.then(onFulfilled, onRejected)
- Both
onFulfilledandonRejectedare optional arguments:
- If
onFulfilledis not a function, it must be ignored.- If
onRejectedis not a function, it must be ignored.- If
onFulfilledis a function:
- it must be called after
promiseis fulfilled, withpromise’s value as its first argument.- it must not be called before
promiseis fulfilled.- it must not be called more than once.
- If
onRejectedis a function,
- it must be called after
promiseis rejected, withpromise’s reason as its first argument.- it must not be called before
promiseis rejected.- it must not be called more than once.
onFulfilledoronRejectedmust not be called until the execution context stack contains only platform code. [3.1].onFulfilledandonRejectedmust be called as functions (i.e. with nothisvalue). [3.2]thenmay be called multiple times on the same promise.
- If/when
promiseis fulfilled, all respectiveonFulfilledcallbacks must execute in the order of their originating calls tothen.- If/when
promiseis rejected, all respectiveonRejectedcallbacks must execute in the order of their originating calls tothen.
thenmust return a promise [3.3].promise2 = promise1.then(onFulfilled, onRejected);
- If either
onFulfilledoronRejectedreturns a valuex, run the Promise Resolution Procedure[[Resolve]](promise2, x).- If either
onFulfilledoronRejectedthrows an exceptione,promise2must be rejected witheas the reason.- If
onFulfilledis not a function andpromise1is fulfilled,promise2must be fulfilled with the same value aspromise1.- If
onRejectedis not a function andpromise1is rejected,promise2must be rejected with the same reason aspromise1.The Promise Resolution Procedure
The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as
[[Resolve]](promise, x). Ifxis a thenable, it attempts to makepromiseadopt the state ofx, under the assumption thatxbehaves at least somewhat like a promise. Otherwise, it fulfillspromisewith the valuex.This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant
thenmethod. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonablethenmethods.To run
[[Resolve]](promise, x), perform the following steps:
- If
promiseandxrefer to the same object, rejectpromisewith aTypeErroras the reason.- If
xis a promise, adopt its state [3.4]:
- If
xis pending,promisemust remain pending untilxis fulfilled or rejected.- If/when
xis fulfilled, fulfillpromisewith the same value.- If/when
xis rejected, rejectpromisewith the same reason.- Otherwise, if
xis an object or function,
- Let
thenbex.then. [3.5]- If retrieving the property
x.thenresults in a thrown exceptione, rejectpromisewitheas the reason.- If
thenis a function, call it withxasthis, first argumentresolvePromise, and second argumentrejectPromise, where:
- If/when
resolvePromiseis called with a valuey, run[[Resolve]](promise, y).- If/when
rejectPromiseis called with a reasonr, rejectpromisewithr.- If both
resolvePromiseandrejectPromiseare called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.- If calling
thenthrows an exceptione,
- If
resolvePromiseorrejectPromisehave been called, ignore it.- Otherwise, reject
promisewitheas the reason.- If
thenis not a function, fulfillpromisewithx.- If
xis not an object or function, fulfillpromisewithx.If a promise is resolved with a thenable that participates in a circular thenable chain, such that the recursive nature of
[[Resolve]](promise, thenable)eventually causes[[Resolve]](promise, thenable)to be called again, following the above algorithm will lead to infinite recursion. Implementations are encouraged, but not required, to detect such recursion and rejectpromisewith an informativeTypeErroras the reason. [3.6]
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise#Promise_%E5%8E%9F%E5%9E%8B
语法
new Promise( function(resolve, reject) {...} /* executor */ );参数
- executor
- executor是带有
resolve和reject两个参数的函数 。Promise构造函数执行时立即调用executor函数,resolve和reject两个函数作为参数传递给executor(executor 函数在Promise构造函数返回新建对象前被调用)。resolve和reject函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。executor 内部通常会执行一些异步操作,一旦完成,可以调用resolve函数来将promise状态改成fulfilled,或者在发生错误时将它的状态改为rejected。- 如果在executor函数中抛出一个错误,那么该promise 状态为rejected。executor函数的返回值被忽略。
例子
https://www.jianshu.com/p/459a856c476f
解决回调地狱的方法:
const request = url => { return new Promise((resolve, reject) => { $.get(url, data => { resolve(data) }); }) }; // 请求data1 request(url).then(data1 => { return request(data1.url); }).then(data2 => { return request(data2.url); }).then(data3 => { console.log(data3); }).catch(err => throw new Error(err));
http://www.cnblogs.com/lvdabao/p/es6-promise-1.html
function runAsync(){ var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.log('执行完成'); resolve('随便什么数据'); }, 2000); }); return p; } runAsync1() .then(function(data){ console.log(data); return runAsync2(); }) .then(function(data){ console.log(data); return '直接返回数据'; //这里直接返回数据 }) .then(function(data){ console.log(data); });
Q库
http://documentup.com/kriskowal/q/#
https://github.com/kriskowal/q
If a function cannot return a value or throw an exception without
blocking, it can return a promise instead. A promise is an object
that represents the return value or the thrown exception that the
function may eventually provide. A promise can also be used as a
proxy for a remote object to overcome latency.On the first pass, promises can mitigate the “Pyramid of
Doom”: the situation where code marches to the right faster
than it marches forward.step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); }); });With a promise library, you can flatten the pyramid.
Q.fcall(promisedStep1) .then(promisedStep2) .then(promisedStep3) .then(promisedStep4) .then(function (value4) { // Do something with value4 }) .catch(function (error) { // Handle any error from all above steps }) .done();With this approach, you also get implicit error propagation, just like
try,
catch, andfinally. An error inpromisedStep1will flow all the way to
thecatchfunction, where it’s caught and handled. (HerepromisedStepNis
a version ofstepNthat returns a promise.)The callback approach is called an “inversion of control”.
A function that accepts a callback instead of a return value
is saying, “Don’t call me, I’ll call you.”. Promises
un-invert the inversion, cleanly separating the input
arguments from control flow arguments. This simplifies the
use and creation of API’s, particularly variadic,
rest and spread arguments.
BlueBird库
http://bluebirdjs.com/docs/getting-started.html
http://bluebirdjs.com/docs/features.html
http://bluebirdjs.com/docs/api-reference.html
API Reference
评价Promise
https://www.zhihu.com/question/25413141
如果着眼于现在和未来一段时间的话,建议用Promise,不论是ES6的还是用Q还是用bluebird,毫无疑问立即马上开始用。
如果眼光放长一点看的话,用了co以后基本上再也不愿回去了,即使是“正宫娘娘”Promise。
这co完全就是用yield/generator实现了async/await的效果啊,第一次见的时候,真是有种天马行空的感觉(原谅我见识少)。
它不仅能够“同步非阻塞”,也几乎没有剥夺我对多个非阻塞操作依赖关系或者竞争关系的精确控制,当我需要精确控制异步流程的时候,回去用Promise甚至callback,当我需要写的爽,一泻千里的时候,用async/await(扯远了)。

浙公网安备 33010602011771号