处理未预料到的 promise 错误,因此不会触发 reject()

Dealing with errors in promises that are unanticipated and thus don't trigger reject()

在下面的 javascript 代码中,为什么错误(由对 promise 中不存在的对象 属性 的赋值生成)没有被 .catch() 捕获promise,但会被 window.onunhandledrejection 函数捕获吗?我希望能够使用 .catch() 捕获我的承诺中的错误,即使它们不是我事先想到的错误,因此没有想过编写代码来显式调用 reject()。

window.onunhandledrejection = function( error ) {
    console.log(error.reason);
};

function test() {
    return new Promise( async function( resolve, reject ) {
        objectThatDoesntExist.property = 1;
    } );
}

test().catch( (error) => { console.log("Caught " + error) } );

new Promise( async function( ...)) 中删除 async,它按预期工作。 async 正在捕获异常并将其变成承诺不期望的被拒绝的承诺。它不是与 new Promise() 构造函数的合同的一部分,您向它传递一个 returns 它应该注意的承诺的函数。

相反,Promise 构造函数会捕获执行器函数中的同步异常,或者等待您调用 resolve()reject() 回调,并且对执行器回调函数返回的任何内容关注为零。

你可以在这里看到,如果你删除 async 关键字,那么它会按预期工作,并且在 .catch().

中捕获异常

function test() {
    return new Promise(function( resolve, reject ) {
        objectThatDoesntExist.property = 1;
    } );
}

test().catch( (error) => { console.log("Caught " + error) } );

注意:有人可能会问“为什么”Promise 构造函数在创建时不支持这种情况 async。这似乎是一件对承诺友好的事情。我不知道决定不支持它的实际逻辑,但我知道每当你在 new Promise() 执行函数中使用 async 时,这通常是你不支持的标志根本不需要 new Promise() 包装器。如果您出于某种原因使用 async,那么您已经有了承诺。如果您已经有承诺,那么您通常不需要将其包装在 new Promise() 中,因为您可以 use/return 您已经拥有的承诺。