Действительно ли Node.js выполняет фоновые задачи ввода-вывода асинхронно? - PullRequest
0 голосов
/ 28 марта 2012

Редактировать: мы можем закрыть. Не является ли действительно асинхронный, неблокирующий JavaScript невозможен?

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. Откройте новую вкладку в браузере.Установите адрес localhost/1.Пока не ходите.
  4. Откройте новую вкладку в браузере.Установите URL-адрес localhost/2.Пока не идите.
  5. Вернитесь к первой вкладке.Нажмите ввод и сразу после перехода на вторую вкладку нажмите Enter.

Результат:

  • консольный журнал:

    вкладка 1: IЯ нахожусь в
    вкладка 1: я закончил
    вкладка 2: Я нахожусь в
    вкладка 2: Я закончил

  • Вкладка 1 ждет 5 секундчтобы получить результат «1».

  • Вкладка 2 также должна ждать 5 секунд, потому что вкладка 1 спит в течение 5 секунд.

В документах говорится, что все асинхроннокроме кода.Только одна нить.Только один запрос за раз.Запросы ставятся в очередь.

Вызовы ввода / вывода должны быть асинхронными, верно?Тогда почему вкладка 2 должна ждать до вкладки 1, если обратный вызов происходит из процесса асинхронного ввода-вывода?

Спасибо.

Ответы [ 3 ]

5 голосов
/ 28 марта 2012

Поскольку ваш sleep блокирует цикл обработки событий.

Замените его на setTimemout(function() { /* Code to run */ }, 5000); и наблюдайте за немедленным ответом /2.

Фактический ввод / вывод асинхронный, но вседействия, которые вы выполняете над вводом / выводом, происходят в цикле событий.Если что-то блокирует цикл обработки событий, все остальное должно ждать, как вы сказали.

РЕДАКТИРОВАТЬ.Для большей ясности взгляните на следующий рисунок ASCII:

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

По сути, только по одному для каждого потока.Поскольку первый обработчик запросов блокируется на 5 секунд (и по существу невозможно обойти вашу файловую систему пальцами в тесте скорости), второй ответ даже не начинает обрабатываться до тех пор, пока первый запрос почти не будет выполнен.

2 голосов
/ 28 марта 2012
  1. В вашем коде нет вызовов I / O
  2. Вы вызываете метод занятого сна в своем коде, т. Е. Вашему коду требуется 5 секунд для обработки. И пока он обрабатывает, больше ничего не может работать на этом экземпляре

Честно говоря, это реальный вопрос или вы просто пытаетесь взломать узел?

1 голос
/ 28 марта 2012

Сон реализован в режиме блокировки и работает на том же двигателе, который является однопоточным.

SetTimeout метод - эквивалентная версия ожидания некоторого времени в JavaScript.

Также учтите, что в JavaScript большая часть должна включать в себя resultHandler, так как продолжение обрабатывается с типизированными параметрами функций для других функций, которые должны вызываться по завершении работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...