首页 > 解决方案 > 当您在 JavaScript Promises 中省略 .catch 时,实际发生了什么?

问题描述

以下两个函数在调用时的行为相同。

function func1() {
    return asyncFunc()
        .then(() => {
            // do something
        });
}

function func2() {
    return asyncFunc()
        .then(() => {
            // do something
        }).catch((err) => {
            throw err;
        });
}

我知道 .catch() 只是Promise.prototype.then(undefined, onRejected)每个MDN 文档的语法糖。但是,当您从承诺链中省略 .catch 时,我对幕后实际发生的情况感到困惑。

当 Promise 链中没有 .catch() 时,幕后究竟发生了什么?.catch((err) => { throw err;});是否以某种方式“神奇地”附加了一个存在?

标签: javascript

解决方案


.catch((err) => { throw err;}) 不会做任何事情,它只会重新抛出错误。所以返回的 Promise.catch将再次被错误拒绝err

Promise.reject(new Error('test'))
.catch(err => {
   console.error(err)
   throw err
})
.catch(err => {
   console.error(err)
})

func1将返回一个可能被该链中发生的某些事件拒绝的 Promise。所以调用者func1可能想要处理那个错误,或者如果调用者进一步传递接收到的 Promise,并且不想处理那个错误,那么调用者也可以省略 catch。

但是“拥有”链的人(最后收到它并且没有将其传递给其他任何人的人)负责处理拒绝情况。

function func1() {
    return asyncFunc()
        .then(() => {
            // do something
        });
}

function callerA() {
   return func1()
}

function callerB() {
    // callerB does not return the promise retuirned by callerA, 
    // and does not pass it to any other function, so it has to handle
    // the rjection case
   callerA().catch(err => {
     
   })
}

拒绝时,js 环境将检查是否在链中的任何地方捕获了此错误。如果不是这种情况,则UnhandledPromiseRejectionWarning可能会抛出 a:

UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。(拒绝编号:1)

或者在浏览器的情况下,错误会记录在控制台中。

js 环境如何处理未处理的拒绝取决于,nodejs 当前发出此警告:

DeprecationWarning:不推荐使用未处理的承诺拒绝。将来,未处理的 Promise 拒绝将使用非零退出代码终止 Node.js 进程。

正如它所说,将在未来的版本中终止应用程序。

对于浏览器,它不太可能在未来终止选项卡。它很可能只会在控制台中记录该错误,但您仍然应该编写代码,就好像未处理的拒绝会终止上下文一样。


推荐阅读