2014-12-18 15 views
0

我有一個(也許微不足道的)問題。我正在使用Node.js包async,特別是async.each方法(https://github.com/caolan/async#forEach)。Node.js async forEach:線程安全的?

考慮下面的代碼:

var arrayOne=[]; 

async.forEach(arrayTwo, 
    function (item, callback){ 
    arrayOne.push(item); // push into arrayOne 
    callback(); // the iterator has completed 
    }, function(err) { 
    // do something with arrayOne 
}); 

是arrayOne.push(項目)安全嗎?

+4

我認爲node.js中的所有內容都是線程安全的 - 它是單線程的,事件驅動的範例,不是? – Siler

+0

這就是我也知道的。這就是爲什麼我說這個問題可能是微不足道的。然而,運行異步的東西仍然讓我有點困惑。 – ZzKr

+0

異步操作是事件驅動的,這意味着它們將在事件發生的將來某個時候發生。如果事件發生時主線程被佔用,則事件處理程序將等待它被釋放。 –

回答

2

所以這裏的答案有點微妙。對於這種情況,您將以arrayOne具有與arrayTwo相同順序的相同項目,但這更像是您的示例代碼不是真正異步的副作用,並且async.forEach沒有做任何過於意想不到的事情/聰明。但是,爲了使其真正可靠,您需要使用可保證訂單的async功能,其中.forEach/.each合同的信件不包含該訂單。 .each只保證在arrayTwo中的每個項目都會調用一次worker函數。它並不保證它會按順序啓動它們,或者在啓動下一步之前等待完成,等等。如果異步的作者決定以相反的順序啓動工作者函數以進行某些性能優化,例如,這將會改變你的副作用。因此,最好不要依賴超出在異步函數的定義/文檔中明確保證的行爲。所以,使用類似async.series的東西會給你一個可靠的方式來做到這一點,而不是在最後arrayOne得到意外的訂單。當然,並行性特徵現在完全不同。

然而,在一個技術說明,在此不涉及「線程安全」的概念作爲節點只有一個執行線程。然而,在處理這種異步代碼時,最終會遇到相同類型的競爭條件,所以在一天結束時,您可以像使用多線程語言一樣對節點中的競爭條件進行編碼。

我記住的最有用的類比是異步代碼是通過交付訂購食品。如果您打電話給3家餐廳並從每家店訂購一份披薩,這並不意味着送貨到達您的門的訂單。

+0

感謝您的回答。我主要關心的不是順序,而是兩個函數編輯'arrayOne'中的相同位置,例如,如果兩個函數都嘗試推入'arrayOne [0]'。但據我瞭解,這不是一個問題,因爲'node.js'確實只有一個線程。 – ZzKr

+0

是的,調用'arrayOne.push'沒有問題。 –