我有这段代码定期调用 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);
最佳答案
Node.js 是一种事件驱动的非阻塞IO 模型
任何 IO 都会作为底层引擎中的单独线程卸载,从而实现并行性。 如果任务是 CPU 密集型的,则无法实现并行性,因为默认情况下 Javascript 是一种阻塞同步语言
但是,有一些方法可以通过将 CPU 密集型任务卸载到不同的进程来实现此目的。
选项1:
exec 或生成一个子进程并在该生成的 Node 应用程序中执行 load() 函数。如果发射的间隔是每 20000 毫秒,这是可以的,因为当另一个发射时,10 秒的过程将完成。
否则,这是危险的,因为它可能会产生太多的 Node 应用程序,耗尽您的系统资源
选项2: 我不知道 self.load() 接受并返回多少数据。如果它很简单并且网络开销可以接受,则将该任务设置为负载平衡的 Web 服务(可能是并行运行的 4 个 Web 服务器),它接受(而不是指向)1M 记录并返回过滤后的记录。
注意
看起来您正在使用 Node 异步并行函数。但请记下文档中的此描述。
Note: parallel is about kicking-off I/O tasks in parallel, not about parallel execution of code. If your tasks do not use any timers or perform any I/O, they will actually be executed in series. Any synchronous setup sections for each task will happen one after the other. JavaScript remains single-threaded.
关于node.js - 如何使函数在后台运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41771958/