JavaScript在一个函数中包含多个子进程

问题描述

我很好奇是否可以在一个功能中运行多个网络工作者/儿童程序。

所以我有一个函数可以调用多个(主线程阻塞,重负载)算法。这需要相当长的时间,因此我希望他们并行运行多个主题以节省时间。

  function calculateThings(division,colorVal) {
    const resultArray = imagetoArray(img,division);

    /* Worker 1 / Child-Process 1 */
    const resultDefaultAlgorithm = algorithmDefault(resultArray,colorVal);
    const resultDefaultimage = arrayToImage(resultDefaultAlgorithm,colorVal);
    /* Worker 2 / Child-Process 2 */
    const resultFAlgorithm = algorithmF(resultArray,colorVal);
    const resultFImage = arrayToImage(resultFAlgorithm,colorVal);
    /* Worker 3 / Child-Process 3 */
    const resultFSAlgorithm = algorithmFS(resultArray,colorVal);
    const resultFSImage = arrayToImage(resultFSAlgorithm,colorVal);

    return [resultDefaultimage,resultFImage,resultFSImage];
  }

如您所见,我希望每个Web Worker /子进程有两个函数调用。这可能吗?

在查看Web Workers时,这似乎只有在每个worker都有自己的文件时才有可能,而我不想/也不知道该怎么做。

解决方法

当然。您可以创建同一工作文件的多个实例。这将创建一个新线程,每个线程与您的主线程并行运行。在该工作人员中,您应该定义可以完成繁重工作的功能。

您可以将函数映射到对象上,以便可以选择将数据发送给工作程序时要执行的功能(如下面的示例所示),或创建每个都有各自独特功能的单独工作程序文件。

下面,我选择了前者。创建您的工作程序的多个实例,并监听message事件以接收您的数据。

向您的员工发送一些说明。您可以在数组中执行此操作,以发送工作人员应执行和响应的事情的列表,例如要调用的函数和要传递的参数。

// app.js

const workerOne = new Worker('worker.js');
const workerTwo = new Worker('worker.js');

workerOne.addEventListener('message',({ data }) => {
  console.log(data); // Received a result!
});

workerTwo.addEventListener('message',({ data }) => {
  console.log(data); // Received a result!
});

workerOne.postMessage([
  {
    action: 'algorithmDefault',// Function to call.
    args: [5,10] // Arguments to pass to function.
  },{
    action: 'arrayToImage',args: [['something',10],13]
  },]);

workerTwo.postMessage([
  {
    action: 'algorithmDefault',args: [2,20]
  },args: [[2,90,'whatever'],9]
  },]);

在工作程序中,还监听message事件以接收来自主线程的指令。遍历这些指令,并使用提供的参数调用适当的操作。您可以立即将所有结果发送回去,也可以将它们收集到一个数组中,然后在循环完成后再发送回去。

// worker.js

const actions = {
  algorithmDefault: (division,colorVal) => {
     // ... return something.
  },arrayToImage: (increment,colorVal) => {
     // ... return something.
  }
};

self.addEventListener('message',({ data }) => {
  const results = [];
  for (const { action,args } of data) {
    const actionToCall = actions[action]; // Get the function to call.
    const resultOfAction = actionToCall(...args); // Calculating...
    results.push(resultOfAction); // Collect the result.
  }
  postMessage(resultOfAction); // Send back the results.
});