我有一项任务在执行时需要大量计算,而没有IO,我不想在执行此任务时阻塞线程。如何在Node.js
中执行此操作?
我需要这样的东西:
var taskManager = require("some-background-task-lib")
var doSomething = function() {
// this code will calculate something and block thread
}
// this line should not block the Node.js event loop, but execute in background, then call the provided function when done
taskManager.executeInBackground(doSomething, function(err, returnValues) {
});
从node.js中阻塞主线程中删除计算密集型内容的常用方法是将这些工作传递给另一个进程。有很多方法可以构建它。
- 集群中,您有一组流程,所有流程都被设计为执行相同的事情,每个流程都会收到不同的传入请求
- 创建一个专门为执行给定任务而设计的特定子进程,并创建该子进程,该子进程在任务期间运行,然后在需要完成该特定任务时完成
- 创建一组子进程和一个工作队列,让每个子进程从队列中获取一个工作项,执行它,反馈结果,然后从队列中获得下一个项目,等等
而且,这些技术可以结合在一起,也可以组合在一起。
在第一种情况下,您只是创建了更多的流程,所有流程都在做相同的事情。
在另外两种情况下,您特别将计算密集型工作转移到子进程,这样主进程就不会受到该工作的负担或阻碍。
有许多库可以帮助提供使用子进程的接口。一个这样的库提供了webWorker类型的接口。
您需要后台工作人员以及web实例和工作人员实例之间的某种通信协议。例如,您可以使用kue创建任务队列
// web worker
var kue = require('kue');
var queue = kue.createQueue();
....
app.post('/calculateSomeCrazyStuff', (req, res, err) => {
queue.create('myLongRunningJobName1', {
fibonacciSequence: 52
}).save((err) => {
if (err) {
return next(err);
}
res.status(204).send();
});
});
// jobs worker
var kue = require('kue');
var queue = kue.createQueue();
queue.process('myLongRunningJobName1', function(job, done) {
// calculate fibonacci
done();
});