如何在快速请求处理程序中编写非阻塞异步函数



All:

我对 Node 异步编程很陌生,我想知道如何编写一些可以处理耗时繁重计算任务的快速请求处理程序,而无需在请求后进行块快速处理?

我认为 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 的理解是,在 1 毫秒延迟之后,它将在单独的线程/进程中触发回调而不会阻止其他重的调用),任何人都可以告诉我如何在不阻止其他请求的情况下做到这一点重()?

谢谢

与其使用setTimeout,不如使用 process.nextTick 或 setInstant(取决于 od 何时运行回调)。但是,将长时间运行的代码放入函数中是不够的,因为它仍然会在一毫秒后阻塞您的线程。

您需要破坏代码并多次运行setInstant或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++ 中编写本机插件,以便在其中使用线程。

有关详细信息,请参阅:

  • 如果当前请求有大量计算,节点.js服务器如何服务下一个请求?
  • 超出 nodejs 中的最大调用堆栈大小
  • 节点;Q 承诺延迟
  • 如何避免 jimp 阻塞代码节点.js
  • NodeJS, Promise and Performance

最新更新