How to write non-blocking async function in Express request handler
本问题已经有最佳答案,请猛点这里访问。
所有:
我是Node异步编程的新手,我想知道如何编写一些Express请求处理程序,它可以处理耗时的繁重计算任务,而不需要块后快速处理请求?
我认为setTimeout可以将作业放在事件循环中,但它仍然会阻止其他请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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延迟之后它将在一个单独的线程/进程中启动回调而不阻止其他重量调用),任何人都可以告诉我如何在不阻塞的情况下执行此操作 其他请求重()?
谢谢
而不是setTimeout最好使用process.nextTick或setImmediate(取决于你希望运行回调的时间)。但将长时间运行的代码放入函数是不够的,因为它仍然会阻塞你的线程,仅仅一毫秒之后。
您需要打破代码并多次运行setImmediate或process.nextTick - 就像在每次迭代中一样,然后从中安排新的迭代。否则你将无法获得任何收益。
例
而不是像这样的代码:
1 2 3 4 5 6 7 8 9 | var a = 0, b = 10000000; function numbers() { while (a < b) { console.log("Number" + a++); } } numbers(); |
你可以使用这样的代码:
1 2 3 4 5 6 7 8 9 10 11 | 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 ++中生成外部进程或编写本机添加,您可以在其中使用线程。
有关详情,请参阅:
- 如果当前请求有大量计算,node.js服务器如何服务下一个请求?
- nodejs中超出了最大调用堆栈大小
- 节点; Q承诺延迟
- 如何避免jimp阻塞代码node.js
- NodeJS,承诺和表现