Promise 的 then、catch、finally 有何区别?如何实现链式调用?
请说明 Promise.prototype.then、catch、finally 三个方法的行为和区别,以及链式调用的原理。
回答
我还是少年
.then(onFulfilled, onRejected):
- 注册成功和失败回调
- 返回一个新的 Promise,使得可以链式调用
- 返回值处理:返回非 Promise 值 → 包装为
Promise.resolve()传递下去;返回 Promise → 等待其状态;抛出异常 → 转为 rejected Promise
.catch(onRejected):
- 语法糖,等价于
.then(null, onRejected) - 捕获前面链中所有未被处理的 reject/异常
- 推荐将 catch 放在链尾
.finally(fn):
- 无论成功或失败都会执行
- 不接受参数,不改变状态和值
- 返回原 Promise(若 finally 回调返回 rejected Promise 或抛异常,则透传该拒绝)
链式调用原理:
doAsync()
.then(r1 => doMore(r1))
.then(r2 => doEvenMore(r2))
.catch(err => handleError(err))
.finally(() => cleanup());
每个 .then() 返回新 Promise,其回调在微任务中注册。若回调返回 Promise,则下一个 .then() 等其完成;若返回值,则直接传入下一个。这样就实现了异步操作的顺序化编排。