如何同步2位网络工作者的邮件?

问题描述 投票:2回答:2

在javascript中,我有两个网络工作者。

var worker1 = new Worker("file.js"),
    worker2 = new Worker("file.js");

此代码在file.js中:

function A() {
    requestAnimationFrame(A);
    postMessage(123);
}
A();

这意味着我有两个同时创建的Web工作者,并同时将消息发送给父级。

但是我如何实现这样的目标?

function GotWorkerMessages(a, b) {
    // a is event from worker1
    // b is event from worker2
}

基本上,我想每次两个工作人员响应时都运行此功能。万一一个人晚于另一个人完成,它不应跳过任何数据。它仍然应该等待,直到两个都响应,以便每个(a,b)对在同一postMessage调用中配对。

javascript web-worker
2个回答
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


0
投票

Tomas回答了您的问题,如果您喜欢rxjs,也可以研究forkjoin(https://www.learnrxjs.io/operators/combination/forkjoin.html

© www.soinside.com 2019 - 2024. All rights reserved.