等待几个网络工作者完成 [英] Wait for several web workers to finish

查看:101
本文介绍了等待几个网络工作者完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个创建多个webworkers的脚本,这些webworkers执行一些工作并在完成后发送消息。

I have a script that creates several webworkers, these webworkers perform some work and send a message when they finish.

问题是我需要从所有这些结果中获取结果然后计算最终解决方案。在其他工作中,他们计算出问题的部分解决方案,主线程使用这些部分解决方案来生成最终答案。

The problem is I need to get the result from all of them and then compute a final solution. In other works, they work out a partial solution of the problem and the main thread uses those partial solutions to generate the final answer.

我怎么能等待所有这些线程完成,Javascript中是否存在类似Java中的invokeAll?

How could I wait for all those threads to finish, is there something in Javascript like invokeAll in Java?

或多或少,我在主线程中的内容:

More or less, what I have in my main thread:

var data = [];

function createWorker(i) {
    var v = new Worker('js/worker.js');
    v.postMessage(i);
    v.onmessage = function(event){
        data.push(event.data);
    };
}

for(var i = 0; i < 100; i++) {
    createWorker(i);
}

//Wait until all have finished somehow


推荐答案

收到最后一个数据后,请调用您的计算最终解决方案函数:

When the last piece of data is received, call your compute-the-final-solution function:

var data = [];

function createWorker(i) {
    var v = new Worker('js/worker.js');
    v.postMessage(i);
    v.onmessage = function(event){
        data.push(event.data);
        if (data.length === 100) {               // <====
            computeFinalSolution();              // <====
        }                                        // <====
    };
}

for(var i = 0; i < 100; i++) {
    createWorker(i);
}

显然,根据需要参数化,但 createWorker 目前没有参数化 i ,所以...

Obviously, parameterize that as you consider necessary, but createWorker isn't currently parameterized other than i, so...

注意数据中的条目可能不符合规定。 i == 0 的工作人员可能无法完成 i == 1 ,只是因为线程调度的变幻莫测或者工作需要更多处理。如果你需要它们,它很容易完成,但我们必须在每次完成时添加一个计数器(或通过数据循环检查):

Note that the entries in data may not be in order. The worker for i == 0 might not complete until after the worker for i == 1, just because of the vagaries of thread scheduling or if the work requires more processing. If you need them in order, it's easily done, but we have to add a counter (or loop through data on each completion to check):

var data = [];
var dataReceived = 0;

function createWorker(i) {
    var v = new Worker('js/worker.js');
    v.postMessage(i);
    v.onmessage = function(event){
        data[i] = event.data;                    // <====
        if (++dataReceived === 100) {            // <====
            computeFinalSolution();              // <====
        }                                        // <====
    };
}

for(var i = 0; i < 100; i++) {
    createWorker(i);
}






如果你想要更多现代,灵活的方法,考虑使用promises,从ES2015(又名ES6)开始,它是JavaScript原生的,并且可以在旧的JavaScript引擎上使用polyfilled:


If you want a more modern, flexible approach, consider using promises, which are native to JavaScript as of ES2015 (aka ES6) and can be polyfilled for use on older JavaScript engines:

function createWorker(i) {
    return new Promise(function(resolve) {
        var v = new Worker('js/worker.js');
        v.postMessage(i);
        v.onmessage = function(event){
            resolve(event.data);
        };
    });
}

var promises = [];
for(var i = 0; i < 100; i++) {
    promises.push(createWorker(i));
}
Promise.all(promises)
    .then(function(data) {
        // `data` has the results, compute the final solution
    });

这也有数据的优势包含结果按顺序,我们不必自己做这项工作。

This also has the advantage that data will contain the results in order, we don't have to do that work ourselves.

以上内容与您当前的代码一致,似乎没有任何错误准备。但通常最好做错误处理:

The above is in line with your current code, which doesn't appear to have any provision for errors. But it's usually best to do error handling:

function createWorker(i) {
    return new Promise(function(resolve, reject) {
        var v = new Worker('js/worker.js');
        v.postMessage(i);
        v.onmessage = function(event){
            // If you report errors via messages, you'd have a branch here for checking
            // for an error and either calling `reject` or `resolve` as appropriate.
            resolve(event.data);
        };
        // EITHER:
        v.onerror = reject; // Rejects the promise if an error is raised by the web worker, passing along the ErrorEvent
        // OR:
        v.onerror = function(event) {
            // Rejects the promise using the error associated with the ErrorEvent
            reject(event.error);
        };
    });
}

var promises = [];
for(var i = 0; i < 100; i++) {
    promises.push(createWorker(i));
}
Promise.all(promises)
    .then(function(data) {
        // `data` has the results, compute the final solution
    })
    .catch(function(error) {
        // something went wrong
    });

这篇关于等待几个网络工作者完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆