JavaScript 一个函数中的多个子进程

JavaScript multiple child-processes in one function

我很好奇是否可以在一个函数中 运行 多个网络工作者/子进程。

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

  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 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]
  },
  {
    action: 'arrayToImage',
    args: [[2, 90, 'whatever'], 9]
  },
]);

在worker中也监听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.
});