Home What happens when new listener is attached when an event is pending?
Reply: 1

What happens when new listener is attached when an event is pending?

prmph
1#
prmph Published in 2018-02-14 18:56:03Z

Say I have a web worker _worker, and I attach a listener to it like so:

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

Let's say I later conditionally attach another listener inside a promise like so:

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

Basically the first listener's job is to set window["test"] to the event data. The promise generator checks to see if window["test"] is already set by the first listener; if not, we attach another listener to resolve the promise when the worker message event is fired.

But what if, 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? Will the second listener be included in the list of listeners to be notified of the event?

Bergi
2#
Bergi Reply to 2018-02-14 19:16:41Z

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

Yes, the second listener will be included in the list of listeners to be notified of the event here. If the event loop is still waiting to call the listeners, the event has not yet really occurred in the main process, even when the worker has already triggered it and it is waiting in the queue.

The edge case where you could indeed miss the event was if the promise was created during the execution of a message listener that runs before the one that creates window.test, i.e. when you have multiple callbacks listening to the same event. Therefore it's always better to install listeners immediately, especially when you are going to make a promise for it anyway. You can create the promise right away:

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

Then use the promise everywhere (as many times as necessary). No need to store-and-cache the data value yourself when promises already do that for you.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.333686 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO