【问题标题】:What happens when new listener is attached when an event is pending?当事件未决时附加新侦听器时会发生什么?
【发布时间】:2023-03-10 21:47:01
【问题描述】:

假设我有一个 web 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"] 是否已经被第一个监听器设置;如果没有,我们附加另一个侦听器以在触发工作消息事件时解决承诺。

但是,如果当我们附加第二个监听器时,worker 已经触发了一个消息事件,而事件循环正在等待触发第一个监听器呢?第二个侦听器是否会包含在要通知该事件的侦听器列表中?

【问题讨论】:

    标签: javascript asynchronous listener web-worker


    【解决方案1】:

    当我们附加第二个监听器时,worker已经触发了一个消息事件,并且事件循环正在等待触发第一个监听器

    是的,第二个侦听器将包含在侦听器列表中,以便在此处收到事件通知。如果事件循环仍在等待调用监听器,则事件还没有真正发生在主进程中,即使工作人员已经触发了它并且它正在队列中等待。

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

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

    然后在任何地方使用承诺(根据需要多次使用)。当 Promise 已经为您执行此操作时,无需自己存储和缓存数据值。

    【讨论】:

    • 谢谢你的回答,很有用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 2017-01-15
    • 2011-03-30
    • 1970-01-01
    • 2019-06-18
    相关资源
    最近更新 更多