Выбор ответа Middle Event loop и libuv обновлено

setImmediate и setTimeout внутри I/O

Вопрос

Что выведет код?

const fs = require('node:fs');
fs.readFile(__filename, () => {
  setTimeout(() => console.log('timeout'), 0);
  setImmediate(() => console.log('immediate'));
});

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Всегда immediate, потом timeout. Колбэк readFile выполняется в фазе poll.

Варианты ответа

  1. Всегда immediate, потом timeoutправильный ответ
  2. Порядок случайный, зависит от загрузки машины
  3. Всегда timeout, потом immediate
  4. Только immediate: таймер с 0 внутри колбэка игнорируется

Разбор

Колбэк readFile выполняется в фазе poll. Следующая фаза после poll это check, где выполняются setImmediate. До таймеров цикл дойдёт только на следующем обороте. Поэтому порядок жёсткий: immediate, затем timeout.

  • «Всегда timeout первым» неверно: фаза timers уже пройдена в этом обороте.
  • «Случайный порядок» верно только для вызова на верхнем уровне скрипта, а не внутри I/O-колбэка.
  • Таймер с задержкой 0 не игнорируется, просто превращается в 1 мс.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме