Рубрики
Без рубрики

Setimeate VS Setimmediate VS Process.NextTick

На поверхности Settimeout с интервалом 0, Process.NextTick и Setimmediate, по-видимому, делают то же самое, но у них есть важные различия.

Автор оригинала: Mark Wilbur.

В чем разница между 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