Выбор ответа Senior Event loop обновлено

setImmediate и setTimeout внутри колбэка ввода-вывода

Вопрос

Node.js. Что выведет код?

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

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

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

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

Коротко

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

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

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

Разбор

Колбэк readFile выполняется в фазе poll. Следующая фаза цикла libuv это check, где выполняются setImmediate, а таймеры будут только на следующем обороте. Поэтому внутри колбэка ввода-вывода immediate всегда первым. Неопределённый порядок бывает в главном модуле, вне колбэков I/O: там всё зависит от того, успел ли истечь таймер к входу в цикл. Таймер не игнорируется, он сработает на следующем обороте.

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

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

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