含义
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) { |