Promise
用于表示一个异步操作的最终完成 (或失败)及其结果值。
状态
function test(resolve, reject) {
var timeOut = Math.random() * 2;
console.log('pending...')
setTimeout(function () {
if (timeOut < 1) {
// fulfilled
console.log('call resolve()...');
resolve('200 OK');
}
else {
// rejected
console.log('call reject()...');
reject('400 error');
}
}, 0);
}
-
待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
var pending = new Promise(test); // pending...
-
已兑现(fulfilled): 意味着操作成功完成。
pending.then((res)=>{console.log(res)}); // 200 OK
-
已拒绝(rejected): 意味着操作失败。
pending.catch((res)=>{console.log(res)}); // 400 error
事实上我们在.then()
函数里面,如果抛出错误也会进入.catch()
函数里面,这是因为Promise.prototype.then
和Promise.prototype.catch
方法返回的是Promise对象。
pending.then((res)=>{throw 'error'}); // 会进入pending.catch()里面
当.catch()
也抛出错误那么就会触发unhandledrejection
事件(在下面有所介绍)。
pending.catch((res)=>{throw 'error'})
有一点你需要注意因为JavaScript是单线程,所以.then()
与.catch()
会在当前作用域执行完后执行。
pending
.then(function (res) {console.log(res)})
.catch(function (res) {console.log(res)});
console.log('start...');
监听拒绝(reject)事件
当 Promise 被拒绝时,会触发rejectionhandled
或unhandledrejection
事件并被派发到全局作用域。
-
rejectionhandled
当 Promise 被拒绝、并且在
reject
函数处理该 rejection 之后会派发此事件。 -
unhandledrejection
当 Promise 被拒绝,但没有提供
reject
函数来处理该 rejection 时,会派发此事件。
通过window.addEventListener
监听Promise拒绝事件。这个事件有两个属性,一个是promise
属性,该属性指向被驳回的Promise;另一个是reason
属性,该属性用来说明Promise被驳回的原因。
window.addEventListener("unhandledrejection", (event)=>{
console.log(event.promise, event.reason, event);
})
链式调用
连续执行两个或者多个异步操作是一个常见的需求,在上一个操作执行成功之后,开始下一个的操作,并带着上一步操作所返回的结果。我们可以通过创造一个Promise链来实现这种需求。
[func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve())
await
用于等待一个
Promise
对象。只能在异步函数(async function)中使用。
-
若Promise正常处理(fulfilled),其回调的resolve函数参数作为await表达式的值,继续执行
async function
。 -
若Promise处理异常(rejected),await 表达式会把Promise的异常原因抛出。
-
若await操作符后的表达式的值不是一个Promise,则返回该值本身。
(async function () {
function test(resolve, reject) {
var timeOut = Math.random() * 2;
console.log('pending...')
setTimeout(function () {
if (timeOut < 1) {
// fulfilled
console.log('call resolve()...');
resolve('200 OK');
}
else {
// rejected
console.log('call reject()...');
reject('400 error');
}
}, 0);
}
window.addEventListener("unhandledrejection", event => {
console.log('unhandledrejection', event.promise, event.reason, event);
})
var pending = await new Promise(test)
.then(function (res) { console.log(res) })
.catch(function (res) { console.log(res) });
// 等待pending运行完 在运行下面代码
console.log('start...');
})()