2016-04-14 59 views
0

我有這樣一段代碼大陣列上運行:如何定期運行任務而不阻塞事件循環?

for (i = 0; i < cars.length; i++) { 
    cars[i] = some_function(cars[i]) ; 
} 

,我應該不會阻塞事件循環運行的時間間隔的代碼。什麼是正確的方法來做到這一點?

+1

你想'setInterval'? –

+1

使用遞歸和'setTimeout'你會得到預期的結果。請看這個[answer](http://stackoverflow.com/questions/33768726/blocking-event-loop) –

+0

不幸的是,你不能,node.js是單線程的,所以每個大任務都會阻塞事件循環。如果你想運行大型任務,你應該在新的過程中完成。 – alexmac

回答

3

對於部分不堵事件循環,你有兩個選擇,甚至更多:

  1. 加載了你的工作再上一個child processworker
  2. 組塊的處理中some_functionprocess.nextTick把控制權回到大塊之間的事件循環

如果可以分塊,你必須弄清楚你的函數沒有任何細節。

對於部分間隔,您應該將代碼包裝在setInterval內。

+0

我使用Express.js框架,我應該在app.js中開始一個子進程,對嗎? 我應該開始一個子進程做這個工作並殺死它,或者開始一個在後臺運行並且作爲惡魔的子進程,並且間隔地執行它的工作? 哪一個更好? – Leo

+0

在你的情況下,似乎更好的是產生一個子進程,然後殺死它。但這取決於間隔超時。如果您有許多卸載任務同時並行執行,您也可以提高一組工作人員的性能。 – migg

1

有一個很好的異步處理程序庫Bluebird,它正在成爲NodeJS異步協調的主要工具。

藍鳥有一個非常有用的方法對設計用於數組:mapmapSeries。使用起來很簡單,可以讓你迭代數組而不會阻塞事件循環,並且使代碼非常易讀:

var Promise = require('bluebird'), 
    cars = ['a', 'b', 'c']; 

// Iterate across cars without blocking the event loop. Each 
// callback will be made in PARALLEL: 
// @see http://bluebirdjs.com/docs/api/promise.map.html 
Promise.map(cars, function(car) { 
    console.log("I'm logging car ' + car + ' but could be any complex code...'); 
}); 

// Iterate across cars without blocking the event loop. Each 
// callback will be made in SERIES. An item will be fully processed 
// before moving on to the next: 
// @see http://bluebirdjs.com/docs/api/promise.mapseries.html 
Promise.mapSeries(cars, function(car) { 
    console.log("I'm logging car ' + car + ' but could be any complex code...'); 
});