html Promise.then和“rejectionhandled”在下次运行事件循环时的执行顺序有何不同?

oxf4rvwz  于 2022-12-02  发布在  其他
关注(0)|答案(1)|浏览(179)

考虑示例1:

var prom1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    console.log("Prom 1 executed");
    reject("Rejected");
  }, 2000);
});

console.log("Before Prom 1");  

window.addEventListener("rejectionhandled", function(event) {
  console.log("Handled Rejection"); //never triggers
});

window.addEventListener("unhandledrejection", function(e) {
  console.log("unhandledrejection");  
  prom1.then(null, function(err) {
    console.log("Caught error");
  });
});

在这种情况下,rejectionhandled不会触发。现在考虑示例2:

var prom1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    console.log("Prom 1 executed");
    reject("Rejected");
  }, 2000);
});

console.log("Before Prom 1");  

window.addEventListener("rejectionhandled", function(event) {
  console.log("Handled Rejection"); //never triggers
});

window.addEventListener("unhandledrejection", function(e) {
  console.log("unhandledrejection");  
  setTimeout(function() {
    prom1.then(null, function(err) {
      console.log("Caught error");
    });
  }, 0);
});

现在在这个例子中rejectionhandled确实运行了。我知道它与微任务/宏任务/事件循环有关。我知道在SO上也有类似的问题,但是我似乎不能在这里应用那个解释。也许这里的解释https://stackoverflow.com/a/57261820/3429430应该意味着每当promise被捕获在unhandledrejection的处理程序中时,它不被认为是附加的unhandledrejection的处理程序之后'的执行。

ipakzgxi

ipakzgxi1#

这是因为在HTML中,在notify about rejected promises算法的步骤5.4中,要求
1.如果 pPromiseIsHandled内部槽为false,则将 p 添加到 settings object 未完成被拒绝承诺弱集
HostPromiseRejectionTracker(promise, "handle")算法中,在步骤5.2中要求
1.如果 settings object 未完成被拒绝承诺弱集不包含 promise,则返回
在第一种情况下,在调度事件之后,p(a.k.a promise),已经被处理了,你确实添加了一个.then(success, failure)处理程序,它的[[PromiseIsHandled]]内部槽现在是true。这样 p 就不会进入“未完成的被拒绝的promise弱集”,当JS引擎调用HostPromiseRejectionTracker(promise, "handle")操作时,它将在引用的5.4步骤处提前退出。
然而,在第二种情况下,当事件已被调度时,其[[PromiseIsHandled]]内部槽仍为false,并且当调用HostPromiseRejectionTracker(promise, "handle")操作时,它将使其到达算法的末尾,直到激发 rejectionhandled 事件为止。
所以我们可以换个说法
它只在最初没有处理的拒绝(导致 unhandledrejection 事件)上触发,但随后获得了附加的处理程序 [在 * unhandledrejection * 事件得到调度之后]

相关问题