I faced some problem when tried to use broadcast channel to communicate between main script and workers. I have code below in main script:
const channel = new BroadcastChannel('my_bus');
const worker = new Worker('worker.js');
const secondWorker = new Worker('second-worker.js');
channel.postMessage('1000');
and the similar code in both workers:
const bc = new BroadcastChannel('my_bus');
bc.onmessage = () => {
console.log('worker get length');
}
The problem is when the message emitted from main script, workers are not loaded yet, so they skip the message. I am sure about it, because if I do something like this, it works fine:
setTimeout(() => {
channel.postMessage('1000');
}, 100)
Is there some way to trigger callback after worker script has been loaded?
As per last comment, I'll wrote my suggestion as answer:
You can make the worker emit a message when they're loaded, and you listen to that message on main script. That usually what we do with web workers: they emit a message to the main thread to say "I'm ready to receive stuff".
A possible implementation could be:
// assumes the first `message` from workers is always the "loaded" ones
const loaded = w =>
new Promise(r => w.addEventListener("message", r, { once: true }));
// Code runs inside async function, so we can use `await`
async function main() {
const channel = new BroadcastChannel("my_bus");
const worker = new Worker("worker.js");
const secondWorker = new Worker("second-worker.js");
await Promise.all([
loaded(worker),
loaded(secondWorker)
]);
// this will be post only once all the workers have been loaded
channel.postMessage("1000");
}
// call the main function
main();
The workers' code will looks like:
const bc = new BroadcastChannel("my_bus");
bc.onmessage = () => {
console.log("worker get length");
};
postMessage("loaded");