javascript - 当事件待处理时附加新监听器时会发生什么?

标签 javascript asynchronous listener web-worker

假设我有一个网络 worker _worker,并且我向它附加了一个监听器,如下所示:

_worker.addEventListener('message', (event) => {
    window["test"] = event.data||"foo"
});

假设我稍后有条件地在 Promise 中附加另一个监听器,如下所示:

if (window["test"] === undefined) {
    _worker.addEventListener('message', (event) => {
        window["test"] = event.data || "foo";
        resolve(window["test"])
    });
}
else {
    resolve (window["test"]);
}

基本上,第一个监听器的工作是将 window["test"] 设置为事件数据。 Promise 生成器检查第一个监听器是否已设置 window["test"];如果没有,我们会附加另一个监听器来在触发工作消息事件时解析 promise 。

但是,如果当我们附加第二个监听器时,工作线程已经触发了消息事件,并且事件循环正在等待触发第一个监听器,该怎么办?第二个监听器是否会包含在要通知事件的监听器列表中?

最佳答案

As we are attaching the second listener, the worker has already fired a message event, and the event loop is waiting to fire the first listener

是的,第二个监听器将包含在此处接收事件通知的监听器列表中。如果事件循环仍在等待调用监听器,则该事件尚未在主进程中真正发生,即使工作线程已经触发了该事件并且正在队列中等待。

您确实可能错过该事件的边缘情况是,如果在执行 message 监听器期间创建了 promise ,而该监听器在创建 window.test 监听器之前运行,即当您有多个回调监听同一事件时。因此,最好立即安装监听器,尤其是当您无论如何都要做出 promise 时。您可以立即创建 promise :

window.test = new Promise(resolve => {
    _worker.addEventListener('message', (event) => {
         resolve(event.data || "foo");
    }, {once: true});
});

然后在任何地方使用该 promise (根据需要多次使用)。当 Promise 已经为您存储和缓存数据值时,无需自己存储和缓存数据值。

关于javascript - 当事件待处理时附加新监听器时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48794320/

相关文章:

javascript - 平滑滚动到页面顶部

javascript - Dynamics 365 版本 9 中的表单上下文

javascript - 是否可以在 JavaScript 中递归调用 'this' ?

javascript - Knockout.js "visible"调用异步函数 - 不工作

android - 如何检查我的 EditText 是否有 TextChangedListener (TextWatcher)?

javascript - 在 Javascript 中删除和更新数组而不进行突变

javascript - Promise 访问 firebase 时返回错误类型

javascript - Node JS Promise.all 和 forEach

java - 使用 AbstractTableModel 获取 JTable 中的选定行

java - 为什么 Android 监听器通常在 Activity 中实现?