Понимание очереди событий node.js и process.nextTick
У меня проблемы с пониманием, как именно process.nextTick
делает свое дело Я думал, что понял, но я не могу воспроизвести то, как я чувствую, что это должно работать:
var handler = function(req, res) {
res.writeHead(200, {'Content-type' : 'text/html'});
foo(function() {
console.log("bar");
});
console.log("received");
res.end("Hello, world!");
}
function foo(callback) {
var i = 0;
while(i<1000000000) i++;
process.nextTick(callback);
}
require('http').createServer(handler).listen(3000);
В то время как foo
в цикле, я отправлю несколько запросов, предполагая, что handler
будет стоять в очереди несколько раз позади foo
с callback
ставиться в очередь только тогда, когда foo
закончен.
Если я прав, как это работает, я предполагаю, что результат будет выглядеть следующим образом:
received
received
received
received
bar
bar
bar
bar
Но это не так, это просто последовательно:
received
bar
received
bar
received
bar
received
bar
я вижу это foo
возвращается перед выполнением callback
что ожидается, но кажется, что callback
NEXT стоит в очереди, а не в конце очереди, за всеми входящими запросами. Так ли это работает? Может быть, я просто не понимаю, как именно работает очередь событий в узле. И, пожалуйста, не указывайте меня здесь. Благодарю.
2 ответа
process.nextTick помещает обратный вызов в следующий тик, который будет выполняться, а не в конец очереди тиков.
Документ Node.js ( http://nodejs.org/api/process.html) говорит: "Обычно он запускается до запуска любых других событий ввода / вывода, но есть некоторые исключения".
setTimeout(callback, 0), вероятно, будет работать больше, как вы описали.
Вы должны обязательно прочитать ссылку, предоставленную fgascon, и, возможно,
https://github.com/joyent/node/issues/3335 для получения дополнительной информации.
Используйте process.nextTick для случаев, когда вы хотите вызвать некоторый код перед любым вводом-выводом, но после возврата вызывающего контекста (обычно потому, что вы хотите зарегистрировать прослушиватели на отправителе события и должны вернуть созданный отправитель, прежде чем вы сможете что-либо зарегистрировать).