请解释这个行为?

问题描述 投票:-1回答:1

我对Timer函数,微任务和事件侦听器的执行顺序有疑问:

let promise = Promise.reject("Err@!");

setTimeout(() => {
        promise.catch(er => console.log(er, "Caught !"));         // (1)
});

window.addEventListener('unhandledrejection', event => console.log("Unhandled Rejection !", event.reason));  //  (2)

// Output 
// >> Unhandled Rejection ! Err@!
// >> Err@! Caught !

[在此情况下,被拒绝的承诺在setTimeout内部被.catch()捕获之前被Unhandled Rejection事件捕获,其原因是,

如果未处理承诺错误,则会发生“未处理的拒绝”微任务队列的结尾(https://javascript.info/microtask-queue#unhandled-rejection

现在考虑另一种情况:

let promise = Promise.reject("Err@!");

setTimeout(() => {       // (1)  ,gets called first

    setTimeout(function () {  // (3) , gets called at last , (after (2))
        promise.catch(er => console.log("caught ", er  ))
    })

});

setTimeout(function () {      // (2) , gets called after (1)
    window.addEventListener('unhandledrejection', event => console.log("Unhandled Rejection !", event.reason));
})

// Output 
//>>  caught  Err@!

在这种情况下,即使在第二个setTimeout中,即使在第二个setTimeout中,promise也会被嵌套处理程序中的catch处理程序捕获,而微任务队列为空,并且窗口事件侦听器仍无法处理被拒绝的诺言...

为什么?

javascript settimeout es6-promise event-loop
1个回答
0
投票

到诺言被拒绝(未处理)时,unhandledrejection处理程序尚未附加,因此它不处理该案件。您可以随时随地附加.catch.then处理程序,如果Promise已被解决/拒绝,它们将立即执行(在微任务中)。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.