我有这个代码定期调用load
函数,该函数在10秒内完成非常大的加载工作。问题是当load
函数被执行时,它会阻塞主流。如果我在执行load
时发送简单的GET请求(如运行状况检查),则GET调用将被阻止,直到load
调用完成。
function setLoadInterval() {
var self = this;
this.interval = setInterval(function doHeavyWork() {
// this takes 10 sec
self.load();
self.emit('reloaded');
}, 20000);
我尝试了async.parallel,但仍然阻止了GET调用。我尝试了setTimeout
但得到了相同的结果。如何让load
在后台运行,以便它不会阻止主流?
this.interval = setInterval(function doHeavyWork() {
async.parallel([function(cb) {
self.load();
cb(null);
}], function(err) {
if (err) {
// log error
}
self.emit('reloaded');
})
}, 20000);
答案 0 :(得分:1)
Node.js是一个事件驱动的非阻塞 IO模型
IO的任何内容都作为底层引擎中的单独线程卸载,因此实现了并行性。 如果任务是CPU密集型的,则无法实现并行性,因为默认情况下Javascript是阻塞同步语言
但是,有一些方法可以通过将CPU密集型任务卸载到其他进程来实现此目的。
<强>选项1:强>
执行或生成子进程并在该生成的节点应用程序中执行load()函数。如果每隔20000毫秒触发一个间隔,那么这是可以的,因为当另一个触发时,10秒过程将完成。
否则它很危险,因为它会产生太多节点应用程序占用你的系统资源
<强>选项2:强> 我不知道self.load()接受和返回多少数据。如果它是微不足道的并且网络开销是可接受的,那么使该任务成为负载平衡的Web服务(可能是4个并行运行的Web服务器),它接受(而不是指向)1M记录并返回过滤后的记录。
注意强>
看起来您正在使用节点异步并行功能。但请在文档中记下此描述。
注意:parallel是并行启动I / O任务,而不是关于代码的并行执行。如果您的任务不使用任何计时器或执行任何I / O,它们实际上将被串行执行。每个任务的任何同步设置部分将一个接一个地发生。 JavaScript仍然是单线程的。