exception与unfulfilled promise的区别及Promise错误处理相关疑问
Promise 错误处理相关疑问解答
如果
throw语句出现在Promise的then处理函数内部,会触发rejection,可将exception和rejection理解为:exception是同步错误,rejection是异步错误。
疑问1:书中此处标注为rejection,是否应该改为unfulfilled?
不需要修改,原表述是准确的。
首先明确Promise的三种核心状态:
pending:待定,也常被称为unfulfilled,指Promise还未被敲定的初始状态fulfilled:已成功,Promise的已敲定成功状态rejected:已失败,Promise的已敲定失败状态
当throw出现在then的回调中时,then方法返回的新Promise会直接被敲定为失败状态,这个状态对应的就是rejection,而不是还处于未敲定的unfulfilled(pending)状态,所以书中用rejection的表述是正确的。
疑问2:此前认为throw抛出的内容始终属于exception,这一认知是否正确?
这个认知是错误的。throw本质只是一个抛出任意值的操作,它最终产生的是同步exception还是异步rejection,完全取决于它所在的执行上下文:
- 同步执行上下文里的
throw,会产生同步exception,会沿当前调用栈向上冒泡,被最近的try/catch捕获 - 若
throw出现在Promise相关的异步上下文中(包括then/catch/finally的回调、async函数内部),抛出的值会被Promise的内部机制直接捕获,转换成当前Promise的rejection原因,不会产生同步exception,也无法被外层的try/catch捕获。
疑问3:为什么exception仅适用于同步代码场景?
这是由JavaScript的执行模型决定的:
同步exception的冒泡逻辑依赖当前的调用栈,throw触发后会沿着调用栈逐层向上查找匹配的catch块,找不到就触发全局的未捕获异常事件。
而异步代码的回调执行时机是在当前调用栈完全清空之后,触发异步操作的原始调用栈已经被销毁,没有办法沿原来的调用栈完成异常冒泡的逻辑,因此同步的exception机制无法覆盖异步场景,才会有rejection这类专门的异步错误处理设计。
内容的提问来源于stack exchange,提问作者Sandra Schlichting
相关产品推荐
相关产品推荐

