我自己做了一些测试,发现.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函数。通常将参数resolve
和reject
称为讨论目的。
为了清理边缘情况,如果执行器在调用其某个参数之前抛出,Promise
将返回一个被拒绝的promise,并将返回promise的拒绝原因设置为抛出的错误。另一方面,如果执行器同步调用resolve
或reject
,然后继续抛出错误,则返回的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');
})
这里,Promise
0在执行器内部被评估为要传递给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
函数中的一个,则会自动忽略对该函数的其他调用。