繁体   English   中英

在Node.js中,setTimeout()是否会阻止事件循环?

[英]In Node.js, does setTimeout() block the event loop?

如果我有一个简单的setTimeout()函数,并将其设置为10秒钟...

整个服务器在那10秒之内都死了??? 这是真的? 这就是我所听到的。

答案是否定的 您的链接是什么Node.js:如何在不阻止事件循环的情况下重新创建“ setTimeout”函数? 显示的不是setTimeout阻止事件循环,而是while循环故意阻止了事件循环。 如果希望服务器速度更快,则不要阻塞事件循环。 诸如setTimeout类的异步回调将非常setTimeout

您是否出于某种原因(例如测试或其他原因)尝试阻止?

另一个发现可能会帮助正在学习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)

那是不对的。 当您调用setTimeout并返回代码时,服务器不会被阻止。 在等待特定计时器触发时,可以自由处理其他事件(可能是其他setTimeout回调)

您似乎感到困惑的链接没有说明setTimeout将被阻止。 相反,该问题中的OP试图创建一个名为wait的自定义函数,其行为类似于setTimeout wait功能是阻止功能setTimeout将不会阻止。

主进程似乎由主机单线程处理,并被setTimeoutwhile阻塞。

但是,此代码还有一种替代方法,可以按预期工作,并且不会阻塞主进程或事件循环:

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

https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM