0

一直在关注这个精彩的教程。作为 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 个查询(另一个关于年表的查询)。

谢谢 !

4

1 回答 1

4

我希望一旦我同时向我的服务器脚本发出 100 个请求,我会在 10 秒后得到并行的 100 个响应。但是这段代码会一一遍历请求。

是的。Node 严格来说是单线程的,因此每个请求都将串行运行。JavaScript 代码中没有并行性(尽管计算机的底层 I/O 子系统可能是并行执行的)。

这肯定不符合 node.js 背后的理念,对吧?

不会。node.js 的理念是在 I/O 事件准备好执行时尽快执行事件处理程序。

请注意,您的“睡眠”功能并没有真正睡眠,而是与 CPU 挂钩 - 因为节点是单线程的,所以所有其他操作都会阻塞 CPU 处理代码 - 如果您的代码正在执行一些实际的 CPU 密集型操作,也会发生同样的情况. 但是,如果您的代码改为执行 I/O 操作(并且设计正确),那么 node 将围绕您的 I/O 阻塞代码安排其他操作。这样想 - node.js 防止代码阻塞 I/O,而不是阻塞 CPU 使用。如果您的代码是 CPU 密集型的,并且您担心它会阻塞其他处理程序,那么您必须将其设计为让给事件循环以让其他处理程序运行。

在这种情况下的另一个观察结果是请求没有按时间顺序处理 - 它们是随机执行的。

是的,这是可能的。您必须记住,node.js 本质上只是一种将“事件处理程序”附加到感兴趣的 I/O 事件的方法。这些 I/O 事件由底层操作系统中的操作触发(例如,已建立套接字连接、已完成文件读取等),并且 node.js 会调用您的处理程序作为响应。

由于操作系统会自己“内部记账”关于事情何时实际发生以及何时认为它们可用于“用户空间”进程,因此您期望它们发生的时间与计算机说它们实际发生的时间之间可能存在差异. 此外,我不认为该节点(甚至操作系统)在调度事件时保证“公平”。

于 2012-05-01T16:58:14.777 回答