В чем разница между Setimeate (обратный вызов, 0)
и Process.NextTick (обратный вызов)
? Как насчет узла Setimmediate (обратный вызов)
?
На поверхности появляется, что все три функции делают то же самое – они выполняют обратный вызов после текущего цикла событий, но перед чем-либо еще. Натуральный вопрос, чтобы спросить, почему есть три разных функция? Давайте запустим эксперимент:
let racer = function() { setTimeout(() => console.log("timeout"), 0); setImmediate(() => console.log("immediate")); process.nextTick(() => console.log("nextTick")); console.log("current event loop"); } racer()
Из вывода мы можем видеть, что эти обратные вызовы не выполняются в том же порядке, в котором они были написаны в исходном коде.
[Running] node "/Users/logicmason/timeouts.js" current event loop nextTick timeout immediate [Done] exited with code=0 in 0.203 seconds
Объяснение
Первый казненный был Process.NextTick
, который помещает свой обратный вызов в передней части очереди событий. Он выполнит после выполнения кода, который в данный момент выполняется, но перед любыми событиями ввода-вывода или таймеры.
Далее – «тайм-аут». Так как мы прошли Сетримс
Тайм-аут 0, до его выполнения нет дополнительной насильственной задержки, и он находится в очередь таймера во время следующего цикла.
Наконец, у нас есть Setimmediate
, что явно не так немедленно, как его имя! Его обратный вызов помещен в проверку очереди следующего цикла цикла событий. Поскольку очередь проверки происходит позже, чем очередь таймера, Setimmediate будет медленнее, чем SettimeOut 0.
Все вообще, петля событий выглядит так:
таймеры
-> Ио
-> Опрос
-> Проверьте
-> Закрыть
-> таймеры
-> …
Таймеры : обратные вызовы от Setinterval
или Сетримс
IO Callbacks : обратные вызовы от I/O События Холостой : Используется внутренне узел между фазами IO и Poll Опрос : Получить новые события ввода/вывода Проверьте : обратные вызовы от Setimmediate
Выполнить здесь Закрыть : обрабатывать закрытые соединения, такие как розеты
Время вызов!
Что вы ожидаете, что вывод следующего кода в узле будет?
let racer1 = function() { setTimeout(() => console.log("timeout"), 0); setImmediate(() => console.log("immediate")); process.nextTick(() => console.log("nextTick")); } let racer2 = function() { process.nextTick(() => console.log("nextTick")); setTimeout(() => console.log("timeout"), 0); setImmediate(() => console.log("immediate")); } let racer3 = function() { setImmediate(() => console.log("immediate")); process.nextTick(() => console.log("nextTick")); setTimeout(() => console.log("timeout"), 0); } racer1() racer2() racer3()
Это то, что вы ожидали?
Первоначально опубликовано logicmason.com