一直关注这个神话般的tutorial。作为Javascript和函数式编程的新手,我想了解非阻塞本质上意味着什么。我有意在我的JS代码中添加了10秒的“睡眠”,以实现阻塞行为。
function route(pathname, handle)
{
console.log("About to route a request for :"+pathname);
if(typeof handle[pathname]==='function')
{
handle[pathname]();
}
else
{
console.log("No request handler for "+pathname);
}
sleep(10000);
console.log("Exiting router");
}
function sleep(milliSeconds)
{
var startTime = new Date().getTime(); // get the current time
while (new Date().getTime() < startTime + milliSeconds); // hog cpu
}
exports.route=route;
此代码用作来自另一个“服务器”脚本的回调,我从浏览器调用该脚本。我预计,一旦我同时向我的服务器脚本发出100个请求,我会在10秒后得到100个并行响应。但是这段代码一个接一个地贯穿了请求。这肯定没有node.js背后的哲学吗?当我在Java servlet中执行这样的错误代码并在Tomcat上运行时,甚至不会发生这种情况!
在这种情况下的另一个观察是,请求没有按时间顺序处理 - 它们是随机执行的。这对我来说听起来不太好!!
我相信我的代码存在一些问题 - 请帮助我理解这里的概念,以及我的2个查询的答案(另一个关于年表的答案)。
谢谢!
答案 0 :(得分:4)
我预计,一旦我同时向我的服务器脚本发出100个请求,我会在10秒后获得100个并行响应。但是这段代码逐一贯穿了请求。
是。 Node严格是单线程的,因此每个请求都将以串行方式运行。 JavaScript代码中没有并行性(尽管计算机的基础I / O子系统可能并行处理)。
这肯定违背了node.js背后的理念吧?
没有。 node.js的理念是在I / O事件准备就绪后尽快执行事件处理程序。
请注意,你的“睡眠”功能并没有真正睡眠,而是它固定CPU - 因为节点是单线程的,所有其他操作都会阻塞CPU运行代码 - 如果你的代码做了一些实际操作就会发生同样的情况CPU密集型操作。但是,如果您的代码正在执行I / O操作(并且设计正确),那么节点将围绕您的I / O阻塞代码安排其他操作。可以这样想 - node.js可以防止代码阻塞I / O,而不是阻止CPU使用。如果你的代码是CPU密集型的,并且你担心它会阻塞其他处理程序,那么你必须设计它以产生事件循环以让其他处理程序运行。
在这种情况下的另一个观察是,请求没有按时间顺序处理 - 它们是随机执行的。
是的,这是可能的。您必须记住,node.js实际上只是将“事件处理程序”附加到感兴趣的I / O事件的一种方法。这些I / O事件由底层操作系统中的操作触发(例如,已建立套接字连接,文件读取已完成等),node.js会响应您的处理程序。
由于操作系统对事物实际发生的时间以及认为可用于“用户空间”的过程进行了自己的“内部簿记”,因此在您希望它们发生的时间和计算机时间之间可能存在差异他们真的发生了。此外,我不认为节点(或者甚至OS)在调度事件时保证“公平”。