问题描述
所以我有一个函数可以调用多个(主线程阻塞,重负载)算法。这需要相当长的时间,因此我希望他们并行运行多个主题以节省时间。
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.
});