含义
Promise
是异步编程的一种解决方案。语法角度来说可以从它来获取异步操作的消息。
Promise
对象具有以下特点。
- 对象的状态不受外界影响。三种状态:
Pending
进行中,Resolved
已完成和Rejected
已失败。 - 一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise
对象的缺点:
- 无法取消
Promise
,一旦建立就会立即执行,无法中断。 - 不设置回调函数会导致
Promise
内部抛出的错误不会反映到外部。 - 当处于
Pending
状态时,无法判断当前进展到哪个阶段(开始还是即将完成)。
基本用法
Promise新建后就会立即执行。
1 | let promise = new Promise(function(resolve, reject) { |
下面是一个Promise
模拟Ajax
的例子。
1 | var getJSON = function(url) { |
Promise.prototype.then()
then(resolveFn, rejectFn)
。
Promise.prototype.catch()
一般来说,不要在then方法里面定义Reject状态的回调函数(即then的第二个参数),总是使用catch方法。
1 | // bad |
如果没有catch
方法指定错误回调函数,Promise
对象抛出的错误不会传递到外层代码,导致运行后没有任何输出。
Chrome不遵守这条规定,会抛出ReferenceError: x is not defined
的错误。Promise
对象依旧会变成rejected
状态。
1 | var someAsyncThing = function() { |
Promise对象可以连续传递。
1 | var promise = new Promise(function(resolve, reject) { |
Promise.all()
var p = Promise.all([p1, p2, p3]);
参数可以不是数组,但必须具有Iterator
接口,且返回的每个成员都必须是Promise实例。
p
的状态由p1
,p2
,p3
决定。
只有三个状态都变成
resolved
,p
的状态才会变成resolved
,此时返回值是p1
,p2
,p3
的返回值组成的数组。只要有一个被
rejected
,p
的状态就会变成rejected
,此时第一个被reject
的promise实例的返回值会传递给p
的回调函数。
1 | // 生成一个Promise对象的数组 |
Promise.race()
var p = Promise.race([p1, p2, p3]);
只要p1
,p2
,p3
中有一个实例率先改变状态,p
的状态就跟着改变。
Promise.resolve()
上面两个方法都会自动做判断参数是否是Promise对象,如果不是,则会调用Promise.resolve()
方法转为Promise对象。
1 | Promise.resolve('foo') |
参数分为四种情况。
参数是Promise实例,则不做任何修改,直接返回实例。
参数是thenable对象,会转为Promise对象,然后立即执行对象的
then
方法。
1 | let thenable = { |
参数不是具有
then
方法的对象,或根本不是对象,则返回新的Promise
对象,状态为resolved
。
1 | var p = Promise.resolve(function() { |
不带任何参数,则返回一个普通的
resolved
的Promise对象。
1 | var p = Promise.resolve(); |
Promise.reject()
方法与Promise.resolve()
一样,只是返回实例的状态为rejected
。
1 | var p = Promise.reject('出错了'); |
附加方法
done
如果以then
或catch
结尾,那么最后一个方法抛出的错误都可能无法捕捉。因此提供一个done
方法保证回调链尾端总能捕捉任何可能出现的错误。
1 | Promise.prototype.done = function (onFulfilled, onRejected) { |
finally
类似jquery
中ajax
的回调函数always
。
1 | Promise.prototype.finally = function (callback) { |