You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何模拟addEventListener同步触发未捕获错误且不中断后续回调

背景

当执行通过addEventListener添加的回调时,浏览器会按顺序执行回调。若其中一个回调执行失败,会同步触发未捕获错误,但不会中断或阻止后续处理器的执行。

例如执行以下代码:

let button = document.createElement("button");
button.textContent = 'Click';
document.body.append(button);

button.addEventListener('click', () => {
  console.log('1st listener');
  throw new Error('error');
});

button.addEventListener('click', () => {
  console.log('2nd listener');
});

console.log("Before click");
button.click();
console.log("After click");

会输出如下日志:

Before click
1st listener
Uncaught Error: error
2nd listener
After click

关键在于错误发生在两个监听器执行之间,但后续监听器仍会正常执行。

问题

我希望在自定义的类addEventListener框架中模拟这一行为(若能直接继承EventTarget就不会有此需求了)。以下示例代码展示了我的目标:

let callbacks = [
  () => { console.log('1st listener'); throw new Error("error"); },
  () => { console.log('2nd listener') },
];

function triggerHandlers() {
  for(let cb of callbacks) {
    try {
      cb();
    } catch(e) { 
      console.error(e); // 如何在此同步触发未捕获错误且不中断for循环?
    }
  }
}

console.log("Before click");
triggerHandlers();
console.log("After click");
可行方案思路
  • 或许可以使用finally块结合递归调用替代for循环?不过这种写法不太规范,我更希望有更直接的非递归方案。
  • 使用内置的EventTarget规避问题,但这对我来说并非可行方案,除非是在代码库中“针对性”模拟上述行为的不规范用法(即不按其预期用途使用)。
不可行方案
  • 通过setTimeout(()=>throw e, 0)(或类似异步方式)重新抛出错误不可行,因为这不是同步操作。

内容的提问来源于stack exchange,提问作者joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:56:06