2016-04-14 93 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...'); 
});