2014-02-25 150 views
2
//defining schemas, models, db connections, etc.. 

http.createServer(function (req, res) { 
    // some irrelevant stuff.. 

    Model.find({name : regex}).exec(function (err, results) { 

    var localArray = []; 

    for (var i = 0, len = results.length; i < len; ++i) { 
     localArray.push(results[i].name); 
     localArray.push(results[i].id); 
    }; // is this for loop blocking? 

    // some more irrelevant stuff.. 
    }); 
}).listen(8080); 

我的回調函數有一個可以很長的for循環(有時候結果長度= 100)。For循環回調。阻止?

我寫了封鎖代碼嗎?如果是的話,我怎樣才能讓它無阻塞?

+2

它是循環阻塞,但它不阻止I/O。如果你需要的話,這很好。 100項不足以打擾循環或JS。 –

+0

感謝您的快速回復。 :) –

+0

而你錯過了response.json(localArray); :) – Zlatko

回答

2

爲了長話短說,答案是肯定的,它是封鎖。此循環運行時收到的任何請求都將排隊。使用子進程來解鎖你的父代碼。它需要你機器成爲多核(不是產生一個過程,而是高效)。

長篇小說:

JavaScript(和Node因此)是單線程的。這個問題的意義是什麼 - 當你的循環運行時,沒有其他函數可以被調用。 解鎖它的唯一方法是使用子進程。你有兩種選擇,每種都有自己的力量和缺點。

  1. 運行一個羣集,以便當一個節點進程「被阻塞」時,您有另一個進程來處理傳入的請求。
  2. 產生一個子進程來運行一些重要的東西,然後報告結果。

第一個選項是非常簡單的,需要你來包裝你的服務器集羣http://nodejs.org/api/cluster.html 但是有機會,你「塊」整個集羣的每個節點進程中運行這個循環。

第二種方法實施起來比較複雜,需要更多的資源。但是,當你必須做一些非常重的和/或可能會導致內存泄漏的事情時,這是驚人的。這可以讓你做的是創建一個單獨的節點進程(這將需要一些內存,並需要幾毫秒的時間來啓動,所以你不能產生數百萬這些傢伙),傳遞一些參數,並等待結果來。您的父母程序將能夠提供即將到來的請求。但是,一旦完成,不要忘記殺死子進程。 http://nodejs.org/api/child_process.html

無論你選擇什麼,請注意,你仍然在同一臺機器上運行,你遇到的下一個瓶頸是你的機器資源。無論如何運行一些基準。迭代超過一百個項目並不會產生一個孩子那麼重,但是如果您迭代數千或更多?...

p.s.反轉循環運行得更快:

for (var i = results.length; i > 0; i--) { 
    //Do something 
};