“Promise.resolve”与“new Promise”构造函数中的不同错误处理

时间:2021-02-25 22:12:08

标签: javascript asynchronous error-handling promise

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

我尝试了 Promise.resolve 和带有解析“值”的承诺构造函数,该构造函数会引发错误(尝试使用未定义的变量以及引发错误的外部函数)。两者都有 .then 和 .catch 跟随。

我想我知道在 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');
    })

1 个答案:

答案 0 :(得分:2)

Promise 构造函数行为

调用promise构造函数的语法是

Promise( executorFunction)

这导致 Promise 在返回构造的承诺之前同步调用带有两个函数参数的执行器函数。出于讨论目的,通常调用参数 resolvereject

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

案例 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 子句并打印“这实际上被打印了”;

标准(永久链接)

如果执行程序抛出异常,ECMA Script 2015 (“ES6”) 标准要求构造函数调用 25.4.3.1 部分第 10 步中返回的 promise 的 reject 函数。但是,如果 Promise 已被同步解析或拒绝,则这不会影响它的状态:如果之前已调用过对 resolve/reject 函数的其他调用,则会被静默忽略。

相关问题