简体   繁体   English

网络工作者是否有某种加载事件?

[英]Is there some kind of load event for web-workers?

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");

I found this Question/Answer trying to resolve an issue with web workers where it APPEARED that one cannot immediately post to an instantiated worker.我发现这个问题/答案试图解决网络工作者的问题,其中出现无法立即发布到实例化工作者的问题。

The solution was easier than implementing a loaded message for all the different workers.该解决方案比为所有不同的工作人员实现加载的消息更容易。 Simply pass in a name to define a scope for each worker.只需传入一个名称即可为每个工作人员定义范围。

const worker = new Worker("worker.js", { name: 'worker-type-1', type: 'module' );

The reason that this resolved the issue is that if all workers are a part of the same scope (''), if you immediately post to the worker after instantiating it, that post will be listened to by the first available worker of the same scope.这解决了这个问题的原因是,如果所有工作人员都属于同一范围(''),如果您在实例化后立即发布给工作人员,那么该帖子将被同一范围内的第一个可用工作人员收听. Naming the new worker prevents this issue.命名新工作人员可以防止出现此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM