Promise
对象是一个代理对象(代理一个值),被代理的值在Promise
对象建立时多是未知的。javascript
Promise
对象有三种状态:pending
(初始状态)、fulfilled
(成功状态)、rejected
(失败状态)。java
Promise
对象的状态一旦由pending
变为fulfilled
或rejected
将没法再更改。promise
Promise
对象的状态变为fulfilled
后,经过then()
方法执行回调函数;状态变为rejected
后,经过catch()
方法执行回调函数。dom
在 ES2018 中引入了finally()
,表示该Promise
执行结束后(不管是"then
"仍是"catch
"致使的结束)都会执行传入finally
方法的回调函数,回调函数无参数。异步
经过new
运算符能够建立Promise
实例,惟一参数是带有 resolve
和reject
两个参数的 executor
函数。resolve
和reject
函数被调用时,分别将Promise
的状态改成fulfilled
(完成)或rejected
(失败),两个函数都接受一个参数,做为成功(或失败)的信息传递给对应的处理方法(then
或catch
)。函数
let p = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve('resolve');
} else {
reject('reject');
}
}, 1000);
});复制代码
上述例子中,1 秒后随机把Promise
对象的状态改成fulfilled
(完成)或rejected
(失败)。ui
被建立的Promise
对象会当即执行executor
函数,若是咱们还须要在该异步函数结束后再作点什么,就须要调用Promise
对象的then()
、catch()
和finally()
方法。(三个方法都会返回一个新的Promise
对象,所以能使用"链式操做")spa
接上例子:prototype
p.then(res => {
console.log(res); // 'resolve'
}).catch(err => {
console.log(err); // 'reject'
}).finally(()=>{
console.log('finally'); // 一定执行
});复制代码
能够看出,then()
和catch()
方法传入的是一个回调函数,该回调函数有惟一参数,对应的是resolve
和reject
函数传入的参数。finally()
一样是传入一个对调函数,不一样的是该回调函数无参数。代理
场景1:多个Promise
须要依次执行。(Promise.prototype.then()
能够传入另外一个Promise对象)
const promise1 = new Promise(...);
const promise2 = new Promise(...);
const promise3 = new Promise(...);
// promise1成功执行后再执行promise2,再是promise3
promise1.then(promise2).then(promise3);复制代码
场景2:多个Promise
须要都成功。(静态方法:Promise.all()
)
const promise1 = new Promise(...);
const promise2 = new Promise(...);
const promise3 = new Promise(...);
// promise1/2/3 均成功后再执行 then ( 其中一个失败也不会执行 then )
Promise.all([promise1, promise2, promise3]).then(callback(){...});复制代码
场景3:多个Promise
只须要其中一个成功。(静态方法:Promise.race()
)
const promise1 = new Promise(...);
const promise2 = new Promise(...);
const promise3 = new Promise(...);
// promise1/2/3 任意一个成功后执行 then
Promise.race([promise1, promise2, promise3]).then(callback(){...})
复制代码
Promise.resolve()
用于生成一个状态为fulfilled
的Promise
对象。其参数与.prototype.resolve()
一致。
let p1 = Promise.resolve('resolve');
// 等效以下代码
let p2 = new Promise((resolve, reject) => {
resolve('resolve');
});复制代码
Promise.reject()
用于生成一个状态为rejected
的Promise
对象。其参数与.prototype.reject()
一致。
let p1 = Promise.reject('resolve');
// 等效以下代码
let p2 = new Promise((resolve, reject) => {
reject('resolve');
});复制代码
其实上面的介绍中,彻底没有说起then()
的第二个参数,由于其做用与catch()
方法一致。看下面例子:
let p = new Promise((resolve, reject) => {
reject('reject');
})
p.then(res => { }, err => {
console.log(err); // 'reject'
});
p.catch(err => {
console.log(err); // 'reject'
});
复制代码
当then()
/catch()
/finally()
不传入参数,都会返回与原Promise
对象相同(但不相等)的新Promise
对象。看以下例子:
// 不传参的"then"
let p1 = Promise.resolve('resolve');
let p2 = p1.then();
p2.then(res => {
console.log(res); // 'resolve'
});
console.log(p1 === p2); // false
// 不传参的"catch"
let p3 = Promise.reject('reject');
let p4 = p3.catch();
p4.catch(res => {
console.log(res); // 'reject'
});
console.log(p3 === p4); // false
// 不传参的"finally"
let p5 = Promise.resolve('resolve');
let p6 = p5.finally();
p6.then(res => {
console.log(res); // 'resolve'
});
console.log(p5 === p6); // false
复制代码
当then()
或catch()
的参数是有返回值的回调函数A
,then()
或catch()
会返回一个状态为fulfilled
的Promise
对象。新Promise
对象的then()
方法的回调函数的参数就是回调函数A
的返回值。
注意,状态为reject
的Promise
对象在then()
的第一个对调函数返回会致使报错。
注意,finally()
的对调函数"return
"并不会影响新的Promise
对象的then()
或catch()
方法的回调函数的参数值。
若是以为文字描述有点绕,看下面例子:
// 'resolve'状态被处理后的'return'
Promise.resolve('resolve').then(() => {
return 'return1'
}).then(res => {
console.log(res)
}); // 'return1'
// 'reject'状态被处理后的'return'
Promise.reject('resolve').catch(() => {
return 'return2'
}).catch(err => {
console.log('catch:', err)
}).then(res => {
console.log('then:', res)
}); // 'then: return2'
// 'finally'的'return'只会返回与原promise相同的对象
Promise.resolve('resolve').finally(() => {
return 'return3'
}).then(res => {
console.log(res)
}); // 'resolve'
// 'reject'状态未被处理的'return'
Promise.reject('reject').then(() => {
return 'return4'
}).then(res => {
console.log(res);
}); // 报错!!复制代码
resolve()
(包括Promise.reject()
和Promise.prototype.reject()
)除了上面介绍的用法,还能传入thenable
(即,带有then方法的对象),返回的Promise
对象的最终状态由then
方法执行决定。
注意,thenable
的then()
方法只有传入惟一一个回调函数才会被执行,其余参数会被忽略。
看以下例子:
let thenable = {
then(cb1, cb2) {
cb1('cb1');
cb2('cb2');
}
}
// Promise.resolve()
Promise.resolve(thenable).then(
res1 => {
console.log(res1); // 'cb1'
},
res2 => {
console.log(res2); // 不会执行
}
).catch(err => {
console.log(err); // 不会执行
});
// Promise.prototype.resolve()
new Promise((resolve, reject) => {
resolve(thenable);
}).then(res => {
console.log(res); // 'cb1'
});复制代码