javascript - Node.js 真的异步执行后台 I/O 任务吗?

标签 javascript http node.js asynchronous

编辑:我们可以关闭了。 Isn't truly asynchronous, non-blocking javascript impossible?

<小时/>
var PATH = require ("path");
var URL = require ("url");

var sleep = function (ms){
    var start = new Date ().getTime ();
    while ((new Date ().getTime () - start) < ms);
}

require ("http").createServer (function (req, res){
    if (URL.parse (req.url).pathname === "/1"){
        console.log ("tab 1: I'm in");
        PATH.exists ("test", function (exists){

            sleep (5000);

            res.writeHead (200, {"Content-Type": "text/plain"});
            res.end ("1");
            console.log ("tab 1: I'm done");
        });
    }else{
        console.log ("tab 2: I'm in");
        res.writeHead (200, {"Content-Type": "text/plain"});
        res.end ("2");
        console.log ("tab 2: I'm done");
    }
}).listen (80);
  1. 将内容复制到文件中。
  2. 执行文件。
  3. 在浏览器中打开新选项卡。将 url 设置为 localhost/1。还不走。
  4. 在浏览器中打开新选项卡。将 url 设置为 localhost/2。还不走。
  5. 返回第一个选项卡。按 Enter 键,然后在更改到第二个选项卡后立即按 Enter 键。

结果:

  • 控制台日志:

    选项卡 1:我在
    选项卡 1:我完成了
    选项卡 2:我在
    选项卡 2:我完成了

  • 选项卡 1 等待 5 秒以接收结果“1”。

  • 标签 2 也必须等待 5 秒,因为标签 1 正在休眠 5 秒。

文档说,除了代码之外,所有内容都是异步的。只有一根线程。一次只能发出一个请求。请求已排队。

I/O 调用应该是异步的,对吧?那么如果回调来自异步 I/O 进程,为什么选项卡 2 必须等待选项卡 1 呢?

谢谢。

最佳答案

因为您的 sleep 正在阻塞事件循环。

将其替换为 setTimemout(function() {/* Code to run */}, 5000); 并观察 /2 立即响应。

实际的 I/O 是异步的,但您对 I/O 执行的所有操作都发生在事件循环中。如果有什么东西阻塞了事件循环,那么其他一切都必须等待,就像你说的那样。

编辑。为了更清楚地了解,请查看以下 ASCII 图形:

Event Loop Thread: ------+req1HandlerExistsCall+-------+req1Wait5Sec++++++++++++++++++++++++++req2ExistsCall+-------+req2Immediate+-------------
         HTTP I/O: -+req1+--------------------------------------+req2+--------------------------------------+req1Response+--------+req2Response+
         File I/O: ----------------------------+exists1+----------------------------------------------------+exists2+---------------------------

基本上,每个线程一次只能有一个。由于第一个请求处理程序会阻塞 5 秒(并且在速度测试中基本上不可能用手指击败您的文件系统),因此直到第一个请求几乎完成后,第二个响应才会开始处理。

关于javascript - Node.js 真的异步执行后台 I/O 任务吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9896980/

相关文章:

iphone - 区分 iPhone 网络浏览器和 iPhone 应用程序用户代理

node.js - Node 需要的 TypeScript 类型信息

node.js - 使用jade作为纯文本的模板语言

http - 如果删除仅部分成功,要使用正确的 http 状态代码吗?

java - JSP 验证用户来自上一页

javascript - 有没有办法使用哈希/校验和来确保已发布的 npm 包的完整性?

javascript - React-ClickDrag 子组件回调

javascript - 对于具有相同类的多个元素,仅影响 jquery 中单击的元素

javascript - 在 svg 之上有真实的图像

javascript - 为什么JavaScript数组的最大索引是4294967294而不是4294967295?