因此,我基本上是对数组中的对象执行很多操作。因此,我决定使用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
。我已经调试了很长一段时间,并确认创建了10个工人。我感觉自己在做一些愚蠢的错误,但是有人可以解释吗?
Run it here on JSFiddle
最佳答案
您在处理消息之前在最后一个工作程序上调用terminate
,因此最后一个工作程序不会输出任何内容。
发生这种情况是因为worker
变量实际上是全局变量,而不是局部变量。您可以将var worker
替换为let worker
以使其成为局部变量。如果您担心let
浏览器的兼容性,请使用Array
来存储工作程序,或者只是创建一个函数作用域。
现在,在最后一个工作程序上调用终止,因为在循环结束时var worker
变量将被设置为最后一个工作程序。请注意,循环将在任何工作程序开始处理之前完成执行(因为循环是同步代码)。
在原始代码中,您不必在每个工作线程上调用terminate()
,而是在最后一个工作线程上调用10次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/