Promise 是异步编程的一种解决方案,把异步处理对象和处理规则进行规范化
- 优点:避免了多层嵌套的回调、提供了统一的接口
- 缺点:1) 一旦执行就不能取消
2) 如果不设置回调函数promise内部抛出错误,不会反应到外部
3) pending状态时,不知道具体阶段 - 特点:1) 状态只由异步操作的结果决定 2) 状态改变后,不能再次变动
- Promise的三种状态
- pending: 初始状态,进行中
- fulfilled: 执行完成
-
rejected: 执行失败
- 基本用法
const promise = new Promise(function(resolve, reject) {
//
if (/* 异步操作成功 */){
resolve(value);
// 将pending变为fulfilled,并将结果作为参数传递出去
} else {
reject(error);
// pending变成rejected,并将错误作为参数传递出去
}
});
promise.then(function(value) {
// success
// resolve的回调
}, function(error) {
// failure
// rejected的回调
});
- Promise方法
- Promise.all(iterable)
接受一个数组作为参数
const p = Promise.all([p1, p2, p3]);
只有当p1、p2、p3的状态都变成fulfilled,p才会变成fulfilled
其中有一个的状态是rejected,p就会变成rejected,第一个被reject的实例的返回值,会传递给p的回调函数。
- Promise.race(iterable)
const p = Promise.all([p1, p2, p3]);
只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
- Promise.resolve(reason)
返回一个的Promise实例
Promise.resolve方法的参数分成四种情况。
(1)参数是一个 Promise 实例
如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。
(2)参数是一个thenable对象
thenable对象指的是具有then方法的对象,比如下面这个对象。
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); // 42
});
上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出 42。
(3)参数不是具有then方法的对象,或根本就不是对象
如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。
const p = Promise.resolve('Hello');
p.then(function (s){
console.log(s)
});
上面代码生成一个新的 Promise 对象的实例p。由于字符串Hello不属于异步操作(判断方法是字符串对象不具有 then 方法),返回 Promise 实例的状态从一生成就是resolved,所以回调函数会立即执行。Promise.resolve方法的参数,会同时传给回调函数。
(4)不带有任何参数
Promise.resolve方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。
所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve方法。
const p = Promise.resolve();
p.then(function () {
// ...
});
上面代码的变量p就是一个 Promise 对象。
需要注意的是,立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。
setTimeout(function () {
console.log('three');
}, 0);
Promise.resolve().then(function () {
console.log('two');
});
console.log('one');
// one
// two
// three
上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。
- Promise.reject(reason)
返回状态位rejected的Promise实例
- Promise prototype
Promise.prototype.then(onFulfilled, onRejected)
Promise.prototype.then方法返回的是一个新的Promise对象,因此可以采用链式写法Promise.prototype.catch(onRejected)
Promise.prototype.catch方法是Promise.prototype.then(null, rejection)的别名,用于指定发生错误时的回调函数。
Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。Promise.prototype.finally(onFinally)
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});