2017-06-28 30 views
1

所以我基本上做了很多對數組中的對象的操作。所以我決定使用webworkers,這樣我就可以以並行方式處理它們。但是,如果我輸入一個包含10個對象的數組,只有9個工作人員會返回一個值。所以我創造了這個簡單的樣機能重現問題:10個webworkers創建,但只有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]); 
} 

因此,基本上,在德陣列中的每個數字被乘以3,並加入到新陣列newnumbers。但是,numbers.length = 10newnumbers.length=9。我調試了一段時間,並驗證了10名工人的創建。

我覺得我在做一些愚蠢的錯誤,但有人可以解釋一下嗎?

Run it here on JSFiddle

回答

1

您在最後一名工人稱terminate它處理訊息話題之前,讓最後一名工人不輸出任何東西。

發生這種情況是因爲worker變量實際上是全局變量而不是本地變量。您可以使用let worker替換var 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/

+0

絕對固定的,所以都是工人也正常終止呀? –

+0

是的,因爲每個迭代中創建的每個worker都會發生'worker.terminate()'調用。在使用全局'var worker'變量實現時,'worker.terminate()'僅在最後一個worker上被調用了10次。 – Cristy

相關問題