代码之家  ›  专栏  ›  技术社区  ›  Thomas Wagenaar

创建了10个webworkers,但只有9个返回值

  •  1
  • Thomas Wagenaar  · 技术社区  · 7 年前

    所以我基本上对数组中的对象进行了很多操作。所以我决定使用webworkers,以便以并行方式处理它们。然而,如果我输入一个包含10个对象的数组,只有9个worker会返回一个值。所以我创建了一个简单的模型来再现这个问题:

    var numbers = [12, 2, 6, 5, 5, 2, 9, 8, 1, 4];
    var create = function(number) {
        var source = 'onmessage = function(e) { postMessage(e.data * 3) }';
        var blob = new Blob([source]);
        var url = window.URL.createObjectURL(blob);
        return new Worker(url)
    }; 
    
    var newnumbers = [];
    for (var i = 0; i < numbers.length; i++) {
        var worker = create();
        worker.onmessage = function(e) {
            newnumbers.push(e.data);
            worker.terminate();
        }
    
        worker.postMessage(numbers[i]);
    }
    

    所以基本上,de数组中的每个数字都乘以3,然后添加到一个新数组中 newnumbers numbers.length = 10 newnumbers.length=9

    我觉得我做错了什么愚蠢的事,但有人能解释一下吗?

    Run it here on JSFiddle

    1 回复  |  直到 7 年前
        1
  •  1
  •   XCS    7 年前

    你打电话 terminate 在处理消息之前的最后一个worker上,因此最后一个worker没有输出任何内容。

    worker 变量实际上是全局变量,而不是局部变量。您可以替换 var worker let worker 使其成为局部变量。如果你担心 let 浏览器兼容性使用 Array 存储worker,或者简单地创建一个函数作用域。

    现在,对最后一个worker调用terminate,因为 循环结束时,变量将设置为最后一个worker。注意,循环将在任何工作者开始处理之前完成执行(因为循环是同步代码)。

    terminate() 终止() 最后的

    var newnumbers = [];
    for (var i = 0; i < numbers.length; i++) {
        let worker = create();
        worker.onmessage = function(e) {
            newnumbers.push(e.data);
            worker.terminate(); // "worker" refers to the unique variable created each iteration
        }
        worker.postMessage(numbers[i]);
    }
    

    演示: https://jsfiddle.net/bqf5e9o1/2/