Search code examples
javascriptclasseventsweb-worker

Why Web worker is creating a new Class Instance again on module import?


We are executing a time taking function on web worker. Also I have a Dispatcher Class that create a single instance for other classes to use looks like below:

class Dispatcher {
constructor() {
        console.log("calling");
        this.events = {};
    }
//some code
}
const dispatcher = new Dispatcher();
export default dispatcher;

I have imported this module in another file named as DataManager Class at the top:

import dispatcher from '../../utility/dispatcher';

export class DataManager {
  notifyRenderer = (data: ResultData): void => {
        dispatcher.dispatch(NOTIFY_EVENT, data);
  }
}

and my web worker is creating a new instance of this class and from here we are triggering a notifyRenderer method written in DataManager Class.

import { DataManager } from "./data-manager";
let dm: DataManager;

addEventListener('message', (e) => {
    if (!dm) {
        dm = new DataManager();
    }

    const res = dm.addOrUpdateData(e.data.input, true);
    dm.notifyRenderer(res);
    postMessage({ type: 'Dispatch', res });
}, false);

Also I am attaching a screenshot of my console showing console.log("calling"); two times. I have no idea why Dispatch class constructor is getting called two times.

enter image description here

Is there any mistake i am doing. Need help on this please.

I feel like module imports might be the problem. Is it?

Adding screenshot trace from worker:

enter image description here

Thank you in Advance!


Solution

  • Everyone learns from their mistake's with practice and the same happened with me here.

    Everything was correct in my modules - the Dispatcher Class, Data Manager Class and instantiate of a new worker thread. The problem was that I created a single instance of Dispatcher Class at the end of that module, as I thought the resulting exports would get cached (as per mjs / require) file caching mechanism. I tried to use import in both the main thread and worker thread, but both threads were creating their own module instance. (My Mistake!)

    I didn't even realize until bergi gave me a hint. The correct way is to send data from worker thread to main thread using postmessage and listen on main thread.

    Sent from worker thread:

    postMessage(dm.addOrUpdateData(e.data.input, true) as ResultData);
    

    Listen on main thread:

    this.worker.onmessage = (e: MessageEvent) => {
                if (!e.data) return;
                dispatcher.dispatch(NOTIFY_EVENT, e.data);
            };
    

    Understand More on Realms and helping links must visit:

    Thanks!