Почему Node.js setImmediate выполняется после обратных вызовов ввода-вывода?

Как новый участник, я не могу комментировать темы, поэтому мне пришлось создать новую тему. Но таким образом я могу прояснить проблему, так что, надеюсь, вы, ребята, сможете мне помочь.

Я много читал о Node.js Event Loop. И я сформировал свое понимание этого на основе следующих материалов:

Цикл событий Node.js
Какого черта цикл событий в любом случае?
Почему setImmediate() выполняется перед fs.readFile() в работах Nodejs Event Loop?

(Пожалуйста, не стесняйтесь предлагать другие материалы, которые являются информативными и точными)

Особенно третья ссылка дала мне лучшее понимание. Но, помня об этом, я не могу понять поведение цикла событий для следующего кода:

var fs = require('fs');
var pos = 0;

fs.stat(__filename, function() {
 console.log(++pos + " FIRST STAT");
});

fs.stat(__filename, function() {
 console.log(++pos + " LAST STAT");
});

setImmediate(function() {
 console.log(++pos + " IMMEDIATE")
})

console.log(++pos + "LOGGER");

Удивительно, но для меня вывод таков:

LOGGER  
FIRST STAT  
LAST STAT  
IMMEDIATE

снимок экрана моего терминала, показывающий вывод, а также версию узла
скриншот вывода из онлайн-кода компилятора rextester.com

Учитывая диаграмму цикла событий, я предполагаю, что поток должен быть следующим:

  1. Интерпретатор сначала запускает две операции статистики.
  2. Очереди интерпретатора обратного вызова setImmedate (событие) в очереди setImmedate
  3. Стек вызовов записывает в журнал
  4. Все очереди событий до фазы опроса ввода / вывода пусты, поэтому цикл обработки событий (EL) продолжается
  5. На этапе опроса ввода / вывода EL собирает события и ставит в очередь оба обратных вызова fs.stat на этапе "Выполнить обработчики ввода / вывода"
  6. EL проверяет фазу проверки и запускает обратный вызов setImmediate
  7. Этот раунд EL заканчивается, и начинается второй раунд
  8. В "запустить завершенные обработчики ввода / вывода" EL запускает оба обратных вызова (их порядок может быть onn-определенным)

Вопрос 1: Какая часть моего анализа / прогноза неверна?

Вопрос 2: В какой момент Event Loop начинает работать? Это начинается с начала приложения (то есть стадии 1)? или он запускается после того, как интерпретатор читает весь код, все задачи синхронизации выполняются в стеке вызовов, а стеку вызовов требуется больше задач, то есть между этапами 3-4?

Заранее спасибо,

1 ответ

setImmediate = выполнить без ожидания ввода-вывода

В https://nodejs.org/docs/v8.9.3/api/timers.html говорится:

Планирует "немедленное" выполнение обратного вызова после обратных вызовов событий ввода / вывода. Возвращает Immediate для использования с clearImmed

шаги:

  1. обратный вызов для первой статистики в очереди ввода / вывода
  2. обратный вызов для последней статистики ставится в очередь в очереди ввода / вывода
  3. обратный вызов для немедленной очереди в очереди немедленных
  4. ЛЕСОЗАГОТОВИТЕЛИ
  5. Если операции ввода / вывода (в 1 и 2) завершены, обратные вызовы в 1 и / или 2 помечаются как готовые к выполнению
  6. Выполните готовые обратные вызовы один за другим (сначала тиммер, затем ввод-вывод, наконец, немедленный). В твоем случае:
    1. Первый стат
    2. Последняя статистика
    3. ЛЕСОЗАГОТОВИТЕЛИ

В случае, если I / O не заканчивается в 5. тогда LOGGER выполнялся до FAT STAT и LAST STAT.

Смотрите также: https://jsblog.insiderattack.net/timers-immediates-and-process-nexttick-nodejs-event-loop-part-2-2c53fd511bb3

Другие вопросы по тегам