2012-03-27 2 views
0

Редактировать: Мы можем закрыть. Isn't truly asynchronous, non-blocking javascript impossible?Действительно ли Node.js выполняет задачи ввода-вывода в фоновом режиме?


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. Вернитесь на первую вкладку. Нажмите «Ввод» и сразу после перехода на вторую вкладку и нажмите «Ввод».

Результат:

  • консоли журнала:

    Вкладка 1: Я в
    вкладке 1: Я сделал
    Вкладка 2: Я в
    вкладке 2: Я закончил

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

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

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

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

Спасибо.

+1

, имеющий поддельный метод 'sleep' в узле * ragequit * – jAndy

ответ

5

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

Заменить его setTimemout(function() { /* Code to run */ }, 5000); и посмотреть /2 ответить немедленно.

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

EDIT. Для большей наглядности ознакомьтесь со следующим графиком ASCII:

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

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

+0

Тогда существует функция exist() synhronous? Тогда почему есть 2 функции, чтобы проверить, существует ли файл? (существует() и существуетSync()). Спасибо –

+0

Нет, '' существует'' является асинхронным, но каждое событие выполняется линейно в одном потоке, поэтому ваша команда '' sleep'' блокирует все действия в течение 5 секунд. Позвольте мне отредактировать мой пост с графикой ASCII, чтобы лучше объяснить. –

+0

Спасибо, я был очень смущен асинхронностью и параллелизмом. Теперь я вижу, что node.js работает так же, как традиционный цикл событий браузера (таймауты, ajax и т. Д.). –

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

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

+0

Вопрос такой реальный, как и большинство других вопросов здесь. –

+0

Вы должны быть ультра умны. Удалите нисходящее направление. Это РЕАЛЬНЫЙ вопрос. –

1

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

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

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

Смежные вопросы