当您从JavaScript承诺中省略.catch时,实际发生了什么?

当您从JavaScript承诺中省略.catch时,实际发生了什么?,javascript,Javascript,以下两个函数在调用时的行为相同 function func1() { return asyncFunc() .then(() => { // do something }); } function func2() { return asyncFunc() .then(() => { // do something }).catch((err) =>

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

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

function func2() {
    return asyncFunc()
        .then(() => {
            // do something
        }).catch((err) => {
            throw err;
        });
}
我知道.catch()只是
Promise.prototype.then(未定义,onRejected)
per的语法糖。然而,当你从一个承诺链中省略.catch时,我很困惑幕后到底发生了什么

当承诺链中没有.catch()时,幕后到底发生了什么?是一个
.catch((err)=>{throw err;})以某种方式被“神奇地”附加?

捕获((err)=>{throw err;})
不会做任何事情,它只会重新抛出错误。因此,
.catch
返回的承诺将被拒绝,并再次出现错误
err

Promise.reject(新错误('test'))
.catch(错误=>{
控制台错误(err)
失误
})
.catch(错误=>{
控制台错误(err)

})
这两个例子在功能上绝对是等价的,没有什么神奇的事情发生在幕后。
Promise
处理程序回调被设计为自动处理抛出的值,并将它们应用于Promise链

考虑以下示例:

Promise.resolve("{") // broken JSON
    .then((json) => {
        return JSON.parse(json)  // Throws SyntaxError
    })
    .catch((err) => {
        throw err; // Throws the same SyntaxError
    })
    .catch((err) => {
        console.error(err); // Logs the SyntaxError
    });
大多数
Promise
实现都有一个功能,当您没有将错误处理程序附加到被拒绝的承诺时,可以记录错误,有些甚至允许您在发生未经处理的拒绝时注册自定义事件处理程序(例如和)。但并非所有运行时都是平等创建的,例如,Edge中的Promise实现没有提供通知用户未处理拒绝的功能

Q:是一个.catch((err)=>{throw err;});以某种方式被“神奇地”附加

不,一点也不

。然后
方法本身返回一个承诺。并且,如果对返回的承诺调用
.catch
方法,则如果该承诺被拒绝,则将调用在catch中传递的处理程序。如果承诺得到解决,处理程序就会被忽略。阅读更多关于JS承诺中错误处理的信息

而且,正如我已经提到的,catch方法并没有神奇地被追加。如果
返回的承诺被忽略,那么
方法将被拒绝,因为您没有捕获它。运行以下代码以更好地理解:

var myPromise=新承诺(函数(解析、拒绝){
设置超时(拒绝,100);
});
我的承诺
。然后(()=>console.log('hi');//什么也不印
我的承诺
.然后(()=>console.log('hi'))

.catch(()=>console.log('hello'));//打印hello
@axiac是的,我得到了异常如何流向任何更高级别的部分,但我的问题更多的是如何发生的。Like是一个
.catch((err)=>{throw err;})神奇地附加到没有.catch()语句的承诺链?@axiac拒绝的承诺不会导致脚本终止,因为它是异步运行的,并且没有要终止的上下文。它只会导致记录一条错误消息,不再执行
。然后执行
。@deceze取决于js环境。在未来的节点版本中,该过程将确实终止。但对于浏览器来说,将来它们不太可能做这样的事情,无论是对于选项卡还是整个浏览器都不可能。奇怪的是,没有一个答案实际上解决了您提出的问题,您传递的“then”函数被预先包装在try/catch块中,即使没有附加.catch处理程序。这就是为什么它不会抛出(只会尖叫未捕获的bla bla…),但可以在出现捕获处理程序的情况下做出反应。是的,这就是我要说的。他们很可能还会将日志添加到边缘,而这并不能真正回答问题。OP想知道当代码中附加了非
catch
时,是否自动附加
catch
来处理错误。