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

时间:2018-06-12 07:56:21

标签: javascript web-worker

当尝试使用广播频道在主脚本和工作者之间进行通信时,我遇到了一些问题。我在主脚本中有以下代码:

spark2-submit  --master yarn/local  --class org.apache.kudu.spark.tools.ImportExportFiles <path of kudu jar>/kudu-spark2-tools_2.11-1.6.0.jar --operation=import --format=<parquet/avro/csv> --master-addrs=<kudu master host>:<port number>  --path=<hdfs path for data> --table-name=impala::<table name>

和两个工人中的类似代码:

const channel = new BroadcastChannel('my_bus');
const worker = new Worker('worker.js');
const secondWorker = new Worker('second-worker.js');

channel.postMessage('1000');

问题是当主脚本发出的消息,工作者还没有加载时,所以他们跳过了消息。我很确定,因为如果我做这样的事情,它可以正常工作:

const bc = new BroadcastChannel('my_bus');

bc.onmessage = () => {
  console.log('worker get length');
}

在加载工作程序脚本后是否有某种方法可以触发回调?

2 个答案:

答案 0 :(得分:1)

根据最近的评论,我将我的建议写为答案:

您可以使工作程序在加载时发出一条消息,然后在主脚本上收听该消息。 这通常是我们对网络工作者的处理方式:他们向主线程发出一条消息,说“我准备好接收东西”。

可能的实现方式可能是:

// 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();

工人的代码如下:

const bc = new BroadcastChannel("my_bus");

bc.onmessage = () => {
  console.log("worker get length");
};

postMessage("loaded");

答案 1 :(得分:0)

我发现此问题/答案试图解决与Web Workers有关的问题,因为它似乎无法立即发布给实例化的Worker。

该解决方案比为所有不同的工作人员实施已加载的消息要容易得多。只需输入一个名称即可为每个工作人员定义一个范围。

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

之所以解决了这个问题,是因为如果所有工作人员都属于同一范围(''),则如果您在实例化后立即发布给该工作人员,该工作将由的第一个可用工作人员收听。相同的范围。为新工作人员命名可以避免此问题。