所以我基本上对数组中的对象进行了大量操作。所以我决定使用网络工作者,这样我就可以并行处理它们了。但是,如果我输入一个包含10个对象的数组,则只有9个工作符会返回一个值。所以我创建了这个简单的模型来重现问题:
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个工作人员。
我觉得我做了一些愚蠢的错事,但有人可以解释一下吗?
答案 0 :(得分:1)
在处理消息之前,您在最后一个工作程序上调用terminate
,因此最后一个工作程序没有输出任何内容。
这是因为worker
变量实际上是全局变量而不是本地变量。您可以将var worker
替换为let worker
,使其成为本地变量。如果您担心let
浏览器兼容性,请使用Array
来存储工作人员,或者只创建一个函数范围。
现在,在最后一个worker上调用terminate,因为var worker
变量将在循环结束时设置为最后一个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]);
}