Search code examples
javascriptweb-worker

Does the event object on worker.onmessage ever contain anything interesting apart from data?


When adding a callback to capture data transferred through web worker pipe, you do usually this:

worker.addEventListener("message", function(event) {
    var data = event.data;
    // Do something with data
      ...
});

I never touched any of the other properties and when I logged the event object into console, I didn't notice anything interesting. Since the creation of the Event object adds some overhead to message transfer I ask:

Q: Is there anything interesting about the Event object in webworker callbacks, or do we always just use event.data?


Solution

  • Since the creation of the Event object adds some overhead to message transfer

    First, that's a moot point. The overhead is almost null here, just don't worry about it.


    Is there anything interesting about the Event object in webworker callbacks

    The MessageEvent is not only used in "classic" workers messaging, but also in various places where a MessageChannel is being used. It will expose different information based on where it's been created. For instance when messaging between two WindowProxy objects, there will be a .source property that helps determining from where the message came from, along with a .origin property, mostly useful for when the emitter is cross-origin.

    But these aren't really interesting for classic Workers since there the emitter is always the context that created the Worker.

    So the only two interesting properties you can look at when receiving a MessageEvent in a Worker are the .data indeed, and the .ports, which will contain the list of all the MessagePort objects that have been transferred in that message.

    // in main script
    const { port1, port2 } = new MessageChannel();
    worker.postMessage(data, [port1]);
    
    // in worker script
    onmessage = ({ data, ports }) => {
      // Here you can access the transferred MessagePort
      const port = ports[0];
      ...
    }
    

    The fact that the same MessageEvent is being used for all the cases where a MessageChannel is used allows to extend that interface and have potentially new features added to all these case, for instance if one day we finally add access to all the transferred data, we'd just have to extend the interface so that it's accessible everywhere at once.