"Promise.resolve" vs "new Promise"构造函数中的不同错误处理



我自己做了一些测试,发现.then()或.catch()中的错误处理程序不会在Promise.resolve(value)的'value'中捕获错误,但会在Promise构造函数resolve(value。

我尝试了Promise.resolve和一个带有resolve"value"的Promise构造函数,该构造函数会引发错误(尝试使用未定义的变量和引发错误的外部函数)。两人都有。然后和。追赶。

我想我的想法是,在Promise.resolve中,"value"是在"发送"给then之前进行评估的,所以JavaScript会抛出一个异常,并在它有机会被.then或.catch捕获之前将其全部关闭。但为什么Promise构造函数中的resolve(value)没有发生同样的情况呢。

只是澄清一下:

在以下情况下,JavaScript报告一个未处理的异常,一切都停止了:


Promise.resolve(someError)
.catch(() => {
console.error('This never gets printed');
})

但是。。。

在下面的情况下,.catch确实捕捉到错误并打印其消息:


new Promise ((resolve, reject) => {
resolve(someError)
})
.catch(() => {
console.error('This actually gets printed');
})

承诺构造函数行为

调用promise构造函数的语法是

Promise( executorFunction)

这导致CCD_ 1在返回构造的promise之前用两个函数参数同步调用executor函数。通常将参数resolvereject称为讨论目的。

为了清理边缘情况,如果执行器在调用其某个参数之前抛出,Promise将返回一个被拒绝的promise,并将返回promise的拒绝原因设置为抛出的错误。另一方面,如果执行器同步调用resolvereject,然后继续抛出错误,则返回的promise将根据调用的参数函数得到解决或拒绝:抛出的错误将被忽略!

案例1

Promise.resolve(someError)
.catch(() => {
console.error('This never gets printed');
})

在调用Promise.resolve方法之前,JavaScript引擎会评估要传递给该方法的参数。如果使用语法或运行时错误评估someError错误,则由于遇到错误,代码执行将停止"一切都停止了";,不调用Promise.resolve,也不会执行以下代码。

情况2

new Promise ((resolve, reject) => {
resolve(someError)
})
.catch(() => {
console.error('This actually gets printed');
})

这里,Promise0在执行器内部被评估为要传递给resolve的参数。由于它出错,JavaScript引擎从不调用resolve。但是,对于执行器提前抛出的情况,Promise定义的行为是返回一个被拒绝的promise,并将原因设置为抛出的错误。稍后调用中的.catch子句并打印"This actual gets printed";

标准(permalink)

如果执行器抛出,ECMA Script 2015("ES6")标准要求构造函数在第25.4.3.1节的步骤10中调用返回的promise的reject函数。然而,如果promise已经被同步解析或拒绝,这不会影响它的状态:如果之前已经调用过resolve/reject函数中的一个,则会自动忽略对该函数的其他调用。

最新更新