Javascript “中的不同错误处理”;“承诺.解决”;vs";“新承诺”;建造师

Javascript “中的不同错误处理”;“承诺.解决”;vs";“新承诺”;建造师,javascript,asynchronous,error-handling,promise,Javascript,Asynchronous,Error Handling,Promise,我自己做了一些测试,发现.then()或.catch()中的错误处理程序没有捕获Promise.resolve(value)的“value”中的错误,而是在Promise构造函数resolve(value)中捕获它 我尝试了Promise.resolve和带有resolve“value”的Promise构造函数,该构造函数会引发错误(尝试使用未定义的变量和引发错误的外部函数)。两人都有。然后和。接球 我想我得到的想法是,在Promise.resolve中,“value”在被“发送”到then之前

我自己做了一些测试,发现.then()或.catch()中的错误处理程序没有捕获Promise.resolve(value)的“value”中的错误,而是在Promise构造函数resolve(value)中捕获它

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

我想我得到的想法是,在Promise.resolve中,“value”在被“发送”到then之前被计算,所以JavaScript会抛出一个异常,并在它有机会被.then或.catch捕获之前将其全部关闭。但是为什么承诺构造函数中的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( executorFunction)
这将导致
Promise
在返回构造的Promise之前,使用两个函数参数同步调用executor函数。每次通常调用参数
resolve
reject
,以便于讨论

要清除边缘情况,
Promise
如果执行者在调用其参数之一之前抛出,则返回被拒绝的承诺,并将返回承诺的拒绝原因设置为抛出的错误。另一方面,如果执行者同步调用
resolve
reject
,然后继续抛出错误,则返回的承诺将根据调用的参数函数进行解析或拒绝:抛出的错误将被忽略

案例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');
})
在这里,
someError
在执行器内部作为传递给
resolve
的参数进行计算。由于它出错,JavaScript引擎从不调用
resolve
。但是对于执行者提前抛出的情况,
Promise
的定义行为是返回拒绝的承诺,并将原因设置为抛出的错误。稍后调用中的
.catch
子句并打印“thiscollygetprinted”

标准(permalink)


如果执行者抛出,ECMA脚本2015(“ES6”)标准要求构造函数在第节的步骤10中调用返回承诺的
拒绝
函数。但是,如果已同步解析或已被拒绝,则这不会影响承诺的状态:如果先前已调用了一对函数中的一个,则对
resolve
/
reject
函数的其他调用将被静默忽略。

承诺构造函数行为

调用承诺构造函数的语法是

Promise( executorFunction)
这将导致
Promise
在返回构造的Promise之前,使用两个函数参数同步调用executor函数。每次通常调用参数
resolve
reject
,以便于讨论

要清除边缘情况,
Promise
如果执行者在调用其参数之一之前抛出,则返回被拒绝的承诺,并将返回承诺的拒绝原因设置为抛出的错误。另一方面,如果执行者同步调用
resolve
reject
,然后继续抛出错误,则返回的承诺将根据调用的参数函数进行解析或拒绝:抛出的错误将被忽略

案例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');
})
在这里,
someError
在执行器内部作为传递给
resolve
的参数进行计算。由于它出错,JavaScript引擎从不调用
resolve
。但是对于执行者提前抛出的情况,
Promise
的定义行为是返回拒绝的承诺,并将原因设置为抛出的错误。稍后调用中的
.catch
子句并打印“thiscollygetprinted”

标准(permalink)


如果执行者抛出,ECMA脚本2015(“ES6”)标准要求构造函数在第节的步骤10中调用返回承诺的
拒绝
函数。但是,如果承诺已被同步解析或已被拒绝,则这不会影响承诺的状态:如果先前已调用该对函数中的一个,则对
resolve
/
reject
函数的其他调用将被静默忽略。

Yes。您的问题到底是什么?如果
someError
是一个抛出的函数调用,则在解释器调用
Promise.resolve()
之前对其进行计算。这与承诺无关,Javascript(或几乎所有语言)就是这样工作的。对参数求值,然后使用这些参数调用函数。因此,如果
someError
是一个抛出的函数调用,那么您显示的代码中没有任何内容能够捕捉到这一点,因为它发生在
Promise.resolve()之前