在javascript中,我有两个网络工作者。
var worker1 = new Worker("file.js"),
worker2 = new Worker("file.js");
此代码在file.js中:
function A() {
requestAnimationFrame(A);
postMessage(123);
}
A();
这意味着我有两个同时创建的Web Worker,并同时将消息发送给父级。
但是我如何实现这样的目标?
function GotWorkerMessages(a, b) {
// a is event from worker1
// b is event from worker2
}
基本上,我想每次两个工作人员响应时都运行此功能。万一一个人晚于另一个人完成,它不应跳过任何数据。它仍应等待,直到两个都响应,以便每个(a,b)对在同一postMessage
调用中配对。
答案 0 :(得分:1)
我会尝试的。作出承诺,当每个工作人员返回消息时,该承诺将解决。等待每个工人的所有承诺。将它们放回原处后。不要忘记处理错误,否则您的应用程序可能会表现异常。
/**
* @description Awaits for a worker to send a message and resolves with that message. Rejects on worker error.
* @param {Worker} worker
* @returns {Promise<MessageEvent>}
*/
function workerMessagePromise(worker) {
return new Promise(function (resolve, reject) {
// if this gets called, message was received OK
function messageReceived(messageEvent) {
// remove the error listener here
worker.removeEventListener("error", workerError);
resolve(messageEvent);
}
// If this gets called, there was an error in the worker
function workerError(error) {
worker.removeEventListener("message", messageReceived);
reject(error);
}
// we use "once" here, we only want one message
worker.addEventListener("error", workerError, { once: true });
worker.addEventListener("message", messageReceived, { once: true });
});
}
/**
* Requires all workers to provide one message, only returns after that
* @param {...Worker} workers
*/
async function AllWorkerMessages(...workers) {
return Promise.all([...workers].map(w => workerMessagePromise(w)));
}
用法类似于:
/**
* Loops for worker messages as long as enabled is true and until a worker throws an error
* @param {{enabled:boolean}} enabledObj
*/
async function loopForWorkerMessages(enabledObj, worker1, worker2) {
while (enabledObj.enabled) {
const messages = await allWorkerMessages(worker1, worker2);
GotWorkerMessages(messages[0], messages[1]);
// Or if you want to be more obscure you can write:
// GotWorkerMessages(...messages);
}
}
const worker1 = new Worker("file.js");
const worker2 = new Worker("file.js");
const enabledObj = {enabled: true};
const loopPromise = loopForWorkerMessages(enabledObj, worker1, worker2);
// later, you can stop the loop and it wont listen to messages and resolve with undefined
setTimeout(()=>enabledObj.enabled=false, 5000);
基于事件的替代方法是拥有一个聚合对象,例如:
const messages = {worker1msg: null, worker2msg: null};
当您收到来自工作人员的消息时,请将其填写在对象中。设置完这两个消息后,执行功能并将其设置回null
。
答案 1 :(得分:0)
Tomas回答了您的问题,如果您对rxjs感兴趣,也可以研究forkjoin(https://www.learnrxjs.io/operators/combination/forkjoin.html)