如果我有一个简单的setTimeout()函数,并将其设置为10秒......
整个服务器在那10秒钟内死了???这是真的?这就是我所听到的。
答案 0 :(得分:21)
答案是否。您的链接Node.js: How would you recreate the 'setTimeout' function without it blocking the event loop?显示的不是setTimeout
阻止事件循环,而是{strong>故意阻止事件循环的while
循环。如果您希望服务器速度很快,则不希望阻止事件循环。诸如setTimeout
之类的异步回调将非常有用。
您是否因某种原因(例如测试或其他原因)试图阻止?)
答案 1 :(得分:6)
另一个发现可能有助于其他正在学习Node.js并对这个问题充满好奇的人,但却被现代浏览器的隐藏行为所欺骗。
代码非常简单,我只是想测试一下我对Node.js的“异步性”的理解。
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
console.log("route begin");
var start = new Date();
setTimeout(function() {
res.render('index', { title: start + ' - ' + new Date()});
}, 20000);//force delay of 20 seconds.
console.log("route end");
});
module.exports = router;
如果我启动三个浏览器窗口(Firefox,更准确),同时打开此路由定义的URL,并从Node.js检查控制台日志,很明显请求不会同时处理强>!
我尝试了几次测试,结果是一样的。
典型的日志输出如下:
route begin at: Fri Aug 28 2015 18:35:57 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:35:57 GMT+0800 (CST)
route begin at: Fri Aug 28 2015 18:36:18 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:36:18 GMT+0800 (CST)
route begin at: Fri Aug 28 2015 18:36:20 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:36:20 GMT+0800 (CST)
而且,奇怪的是,它也没有以串行模式运行(如果Node.js被setTimeout阻止,它应该)。第一个和第二个请求之间的间隔是20秒,但第二个和第三个请求之间的间隔仅为2秒。
在我挠了头很长一段时间之后,我突然想起浏览器在同一主机上有连接限制!
所以,我快速设置了另一个测试,但这次通过发出多个curl命令。
哈利路亚!
route begin at: Fri Aug 28 2015 18:42:51 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:42:51 GMT+0800 (CST)
route begin at: Fri Aug 28 2015 18:42:53 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:42:53 GMT+0800 (CST)
route begin at: Fri Aug 28 2015 18:42:55 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:42:55 GMT+0800 (CST)
答案 2 :(得分:2)
事实并非如此。当您致电setTimeout
并退回代码时,服务器不会被阻止。在等待特定计时器触发时可以自由处理其他事件(可能还有其他setTimeout
回调)
答案 3 :(得分:2)
您似乎感到困惑的链接不表明setTimeout
会阻止。相反,该问题中的OP试图创建一个名为wait
的自定义函数,其行为类似于setTimeout
。 wait
函数是阻塞函数 - setTimeout
不会阻止。
答案 4 :(得分:1)
主要过程似乎由主持人单线化,并被setTimeout
或while
阻止。
但是,这个代码有一个替代方法可以按预期工作,不会阻止主进程或事件循环:
var express = require('express')
var app = express()
function setTimeoutAsync (callback, time) {
setTimeout(function () {
callback()
}, time)
return 0
}
app.get('/', function (req, res, next) {
console.log("route begin")
var start = +new Date()
setTimeoutAsync(function () {
console.log("route done")
res.json({ delay: ((+new Date()) - start) + 'ms' })
}, 5000)
console.log("route end")
});
app.listen(8000)
在终端:
route begin // first page
route end
route begin // second page
route end
route begin // third page
route end
route done // first render
route done // second render
route done // third render
好消息来源:
https://www.journaldev.com/7462/node-js-architecture-single-threaded-event-loop