jjzjj

javascript - 等待几个 web worker 完成

coder 2025-03-05 原文

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

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

我如何才能等待所有这些线程完成,Javascript 中是否有类似 Java 中的 invokeAll 的东西?

或多或少,我的主线程中有:

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

最佳答案

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

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 之外未进行参数化,所以...

请注意,data 中的条目可能没有按顺序排列。 i == 0 的 worker 可能要等到 i == 1 的 worker 后才能完成,这只是因为线程调度的变幻莫测或如果工作需要更多处理。如果您按顺序需要它们,这很容易完成,但我们必须添加一个计数器(或在每次完成时循环遍历 data 进行检查):

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 引擎:

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
    });

这还有一个好处,即 data按顺序包含结果,我们不必自己做这项工作。

以上内容与您当前的代码一致,该代码似乎没有任何错误规定。但通常最好进行错误处理:

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
    });

关于javascript - 等待几个 web worker 完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41423905/

有关javascript - 等待几个 web worker 完成的更多相关文章

  1. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  2. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  3. Ruby:行 "m = Hash.new {|h,k| h[k] = []}"完成了什么而 "Hash.new"没有完成? - 2

    一边学习thisRailscast我从Rack中看到了以下源代码:defself.middleware@middleware||=beginm=Hash.new{|h,k|h[k]=[]}m["deployment"].concat[[Rack::ContentLength],[Rack::Chunked],logging_middleware]m["development"].concatm["deployment"]+[[Rack::ShowExceptions],[Rack::Lint]]mendend我的问题是关于第三行。什么是传递block{|h,k|h[k]=[]}到Has

  4. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  5. ruby - Watir ... sleep 和等待之间的区别 - 2

    有什么显着的区别吗sleep10和wait_until(10)他们似乎都在做同样的事情:WAITING10秒,然后继续下一步 最佳答案 sleep在指定时间内什么都不做。wait_untiltakesablock.它一直等到block评估为真或超时。如果没有给出block,它们的行为相同。 关于ruby-Watir...sleep和等待之间的区别,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/que

  6. ruby - 如何检查一个字符串是否是几个不同值之一? - 2

    我有一个字符串变量,它只能包含6个不同的值。我想检查它是否包含前4个值之一或2个第二值之一。有没有比这更优雅的方式:ifstring.eql?'val1'||string.eql?'val2'||string.eql?'val3'||string.eql?'val4'...elsifstring.eql?'val5'||string.eql?'val6'...end可能类似于ifstringisin['val1','val2','val3','val4']? 最佳答案 您可以使用include?:if['val1','val2','

  7. ruby-on-rails - 自动完成搜索的 Rails 实现 - 2

    我不确定如何为我的搜索功能添加自动完成表单。"get"do%>nil%>我有一个具有自定义操作的Controllerdefquery@users=Search.user(params[:query])@article=Search.article(params[:query])end模型如下:defself.user(search)ifsearchUser.find(:all,:conditions=>['first_nameLIKE?',"%#{search}%"])elseUser.find(:all)endenddefself.article(search)ifsearchArt

  8. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  9. ruby-on-rails - 使用 Rails 5 完成类(class)和模块分配给用户 - 2

    编辑#2这是类(class)ControllerclassCoursesController编辑#1因此,根据下面Jagdeep的回答,我现在完成了以下操作:类(class).rbclassCoursecourse_modules_user.rbclassCourseModulesUsercourses_user.rbclassCoursesUser用户.rbclassUser迁移classCreateCoursesUsers但是,我遇到这样的错误原始问题所以这是previousquestion的延续,然而,这会偏离那个主题,所以这里是一个新的主题。在此之后,我大致得到了我想要开始工作

  10. ruby - 在 Ruby 中禁用 OptionParser 标志的自动完成 - 2

    #!/usr/bin/envrubyrequire'optparse'options={}OptionParser.newdo|opts|opts.on("--languageLANGUAGE",["Ruby","JavaScript"])do|language|options[:language]=languageendend.parse!puts"Language:#{options[:language]}"如果我用./bin/example--languageRu运行它,它将输出:Language:Ruby我想禁用此自动完成/最接近的匹配行为,并在未提供确切名称时引发Option

随机推荐