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