Назад к вопросам
Middle
205
questionbank

Как связаны цикл событий (event loop) и асинхронность в Node.js?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Цикл событий (Event Loop) — это сердце Node.js, которое позволяет ему выполнять асинхронные операции неблокирующим способом. Он управляет порядком выполнения колбэков, зарегистрированных для асинхронных событий.

Когда асинхронная операция (например, чтение файла, сетевой запрос) инициируется в Node.js, она немедленно передается в низкоуровневую библиотеку libuv (или аналогичную). Node.js не ждет ее завершения, а двигается дальше, выполняя следующий код.

После завершения асинхронной операции, libuv уведомляет об этом Event Loop, помещая соответствующий колбэк-функцию в очередь колбэков. Event Loop постоянно проверяет эти очереди и, когда главный поток выполнения становится свободным, забирает колбэк из очереди и выполняет его.

Таким образом, Event Loop обеспечивает асинхронность Node.js, позволяя выполнять другие задачи, пока ожидаем завершения длительных I/O операций. Это предотвращает блокировку главного потока и делает Node.js эффективным для высоконагруженных приложений.

Основные фазы Event Loop:

  • timers: Выполняет колбэки setTimeout() и setInterval().
  • pending callbacks: Выполняет колбэки из отложенной очереди.
  • idle, prepare: Используется внутренне.
  • poll: Ожидает новых событий ввода/вывода и выполняет их колбэки.
  • check: Выполняет колбэки setImmediate().
  • close callbacks: Выполняет колбэки закрытия (например, сокетов).

Микрозадачи (промисы) выполняются после каждой фазы Event Loop, до перехода к следующей.

// Пример асинхронной операции с использованием Event Loop
const fs = require('fs');

console.log('Начало выполнения'); // Первая синхронная операция

fs.readFile('file.txt', 'utf8', (err, data) => {
  // Этот колбэк будет выполнен Event Loop после завершения чтения файла
  if (err) {
    console.error('Ошибка чтения файла:', err);
    return;
  }
  console.log('Содержимое файла:', data);
});

console.log('Конец выполнения - до чтения файла'); // Вторая синхронная операция

В приведенном примере console.log('Конец выполнения - до чтения файла') выполнится до колбэка fs.readFile, поскольку чтение файла является асинхронной операцией, и Event Loop продолжит выполнение скрипта, не дожидаясь его завершения. Колбэк будет помещен в очередь и выполнен позже, когда файл будет прочитан и Event Loop будет готов.