您对我的评论的评论表明该案例与其他答案不同。我真的无法在评论中加入这个解释,所以:
catch 块实际上不会等待 promise 被拒绝。试试这个:
const myPromise = new Promise(() => {
console.log('inside of the promise');
setTimeout(() => { console.log('inside of the timeout function'); throw new Error('ERROR') }, 1000);
}).catch(err => {
console.log('CATCHED ', err);
});
console.log('outside of the catch block, and my promise is', myPromise);
你会发现catch消息的外部是在timeout函数内部的消息之前写入控制台的。此时,承诺尚未解决(待处理)。
当您使用 setTimeout 时,该函数将被添加到 JavaScript 队列的末尾。
编辑
你可以通过在 promise 上调用 reject 来解决这个问题。
const myPromise = new Promise((resolve,reject) => {
setTimeout(() => { reject('ERROR'); }, 1000);
}).catch(err => {
console.log('CAUGHT ', err);
});
这是不同的,因为在这种情况下拒绝函数被保存在一个范围气泡(闭包)中,所以它仍然能够解决。
编辑 2
我确实发现了另一个在 cmets 中有一些讨论的问题:
JavaScript Promises - reject vs. throw
据此,我将修改我的解释。
首先,将 catch blocks 与链接到 promise 的 catch function 分开是很有帮助的。将 Promise 视为使用内置的不可见 catch block 捕获抛出的错误。在处理它时,promise 的 catch block 将调用 'reject',这将触发 catch function。
抛出的错误 => promise 的不可见(隐式)catch 块 => reject() => promise 的 catch() 函数
但是,如果错误是从不同的调用堆栈抛出的,它无法捕获它,它与 setTimeout 一起使用。
抛出错误(在来自 setTimeout 的另一个调用堆栈中)=> 未捕获的异常
链停在那里,因为异常在不同的调用堆栈中冒泡。
但是你仍然可以调用reject,触发catch函数,这就是上面的sn-p代码所做的。
reject => promise 的 catch() 函数
这是一个较短的事件链,直接切入您想要的行为——在 catch 函数中触发代码。