所有
我是Node异步编程的新手,我想知道如何编写一些Express请求处理程序,它可以处理耗时的繁重计算任务,而不会在请求后阻止Express处理?
我认为setTimeout可以将作业放在事件循环中,但它仍会阻止其他请求:
var express = require('express');
var router = express.Router();
function heavy(callback){
setTimeout(callback, 1);
}
router.get('/', function(req, res, next) {
var callback = function(req, res){
var loop = +req.query.loop;
for(var i=0; i<loop; i++){
for(var j=0; j<loop; j++){}
}
res.send("finished task: "+Date.now());
}.bind(null, req, res);
heavy(callback)
});
我想我不明白setTimeout是如何工作的(我对setTimeout的理解是在1ms延迟之后它将在一个单独的线程/进程中激活回调而不会阻止其他重量级的调用),任何人都可以告诉我该怎么做这没有阻止对heavy()的其他请求?
谢谢
答案 0 :(得分:1)
使用process.nextTick或setImmediate(取决于您希望运行回调的时间),而不是setTimeout。但是将长时间运行的代码放入函数是不够的,因为它仍然会阻塞你的线程,仅仅一毫秒之后。
您需要打破代码并多次运行setImmediate或process.nextTick - 就像在每次迭代中一样,然后从中安排新的迭代。否则你将无法获得任何收益。
而不是像这样的代码:
var a = 0, b = 10000000;
function numbers() {
while (a < b) {
console.log("Number " + a++);
}
}
numbers();
你可以使用这样的代码:
var a = 0, b = 10000000;
function numbers() {
var i = 0;
while (a < b && i++ < 100) {
console.log("Number " + a++);
}
if (a < b) setImmediate(numbers);
}
numbers();
第一个会阻塞你的线程(并且可能会溢出你的调用堆栈)而第二个不会阻塞(或者更准确地说,它会在很短的时间内阻塞你的线程10000000次,让其他东西运行在那些时刻之间)。
您还可以考虑在可以使用线程的C / C ++中生成外部进程或编写本机添加。
有关详细信息,请参阅: