1.Promise概述
Promise是异步编程的解决方案。简单来说是一个容器,里面保存了异步操作的结果。Promise有如下特点:
- 对象内部状态不受外界环境影响。promise仅有三种状态pending(进行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果可以决定当前属于哪一种状态。
- 状态一旦确定就无法改变,任何时候都可以得到这个结果。promise的结果改变只有两种状态:从pending->fulfilled、从pending->rejected。只要这两个状态发生就无法改变。
Promise的缺点: - 无法取消Promise,一旦新建就会立即执行,无法中途取消。
- 如果不设置回调函数,promise内部抛出的错误无法被外界捕获。
- 当处于pending状态时,无法得知目前进展到哪一阶段。
注意:在构造Promise的时候,构造函数内部的代码是立即执行的。
2.基本用法
通常使用new Promise构造一个新的promise函数。
1
2
3
4
5
6
7
8const promise = new Promise((resolve, reject) => {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});then()方法:接收两个回调函数,一个作为resolve状态回调,一个作为reject回调
1
2
3
4
5promise.then(res=>{
console.log(res) // value
},err=>{
console.log(err) // error
})catch()方法:接收一个回调函数,用来指定发生错误时的函数。相当于then方法的第二个函数。
1
2
3
4
5
6promise.then(res=>{
console.log(res) // value
})
promise.catch(err=>{
console.log(err) // error
})finally()方法:用于指定不管Promise对象最后状态如何,都会执行的方法。
1
2
3
4promise
.then(res => {···})
.catch(err => {···})
.finally(() => {···})all()方法:用于将多个Promise实例包装成一个新的Promise实例。只有多个Promise的返回状态都为resolve时新的Promise状态才为resolve,任意一个Promise状态为reject时新Promise状态为reject。如果参数Promise定义了自己的catch方法,那么一旦被rejected不会触发Promise.all()的catch方法。如果参数Promise没有自己的catch方法,则调用Promise.all()的catch方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18const p = Promise.all([p1, p2, p3]);
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]race()方法:同样是将多个Promise实例包装成一个新Promise实例,与all不同的是:某一个参数Promise先改变状态,则返回率先改变的那个Promise的返回值,直接结束包装实例。
1
const p = Promise.race([p1, p2, p3]);
any()方法:只要有一个参数实例变成fulfilled状态,包装实例变成fulfilled状态,如果所有的实例都变成rejected状态,包装实例会变成rejected状态。与race方法类似,区别是:Promise.any()不会因为某个Promise变成rejected状态而结束,必须等到所有参数的Promise变成rejected状态才结束。
1
const p = Promise.any([p1, p2, p3]);
resolve()方法:将现有对象转化为Promise对象。
1
2
3Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))resolve参数分四种情况:
参数是一个Promise实例:Promise.resolve不做任何修改、原封不动返回这个实例。
参数是一个thenable对象(具有then方法的对象):Promise.resolve()方法会将这个对象转为Promise对象,然后立即执行thenable对象的then()方法。
1
2
3
4
5
6
7
8
9let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function (value) {
console.log(value); // 42
});参数不是具有then()方法的对象,或根本就不是对象:如果参数是一个原始值,或者是一个不具有then()方法的对象,则Promise.resolve()方法返回一个新的 Promise 对象,状态为resolved。
1
2
3
4
5const p = Promise.resolve('Hello');
p.then(function (s) {
console.log(s)
});
// Hello不带有任何参数:Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。需要注意的是,立即resolve()的 Promise 对象,是在本轮“事件循环”(event loop)的结束时执行,而不是在下一轮“事件循环”的开始时。
1
2
3
4
5
6
7
8
9
10setTimeout(function () {
console.log('three');
}, 0);
Promise.resolve().then(function () {
console.log('two');
});
console.log('one');
// one
// two
// three
reject()方法:返回一个新的 Promise 实例,该实例的状态为rejected。
1 | const p = Promise.reject('出错了'); |