AI তৈরি করেছেমানুষ উন্নত করেছে
Riqli · জীবন্ত নথি · ক্রমাগত আপডেট
যেখানে AI জ্ঞান মানব অনুশীলনের সাথে মিলিত হয়।
বন্ধুদের সাথে শেয়ার করুন

Node.js. Базовый курс от основ до простых realtime коммуникаций. Soft skill. (Node js basics. Основы node js. Node js для начинающих. Event loop node js. Self-study. Training. Coaching.)
Основы Node.js и асинхронная модель
В этом разделе рассматриваются базовые концепции платформы Node.js, ее отличия от браузерного JavaScript и сравнение с другими серверными технологиями, такими как PHP.
Ключевое отличие Node.js от браузерного JavaScript — среда выполнения. В браузере мы манипулируем DOM, а в Node.js создаем веб-серверы, обрабатываем запросы и работаем с файловой системой. Синтаксис языка остается тем же, но меняются цели и подходы.
Сравнение с PHP: В PHP для каждого запроса создается новый процесс, который стартует с чистого листа. В Node.js запускается один процесс, который обрабатывает все запросы в рамках одного event loop. Это позволяет легко создавать общие переменные и кэшировать данные в памяти между запросами, но требует осторожности с долгими синхронными операциями.
Основой асинхронности в Node.js является event loop. Он представляет собой бесконечный цикл, который выполняет задачи из очередей. Существует два типа задач: macro tasks (макрозадачи, например, `setTimeout`, `setInterval`, I/O) и micro tasks (микрозадачи, например, Promise). Сначала выполняется весь синхронный код, затем все микрозадачи, и только потом — макрозадача.
Программа на Node.js завершается, когда в event loop не остается активных macro tasks. Если в коде есть вызов `setTimeout` с колбэком, программа не завершится, пока не пройдет заданное время и колбэк не будет выполнен. Бесконечный цикл синхронного кода (`while(true)`) сделает программу вечно занятой и неспособной обрабатывать другие задачи.
Долгая синхронная вычислительная задача (например, цикл на миллиард итераций) блокирует event loop. Пока она выполняется, Node.js не может обрабатывать другие запросы клиентов или выполнять другие асинхронные операции. Все остальные клиенты будут вынуждены ждать завершения этой задачи, что приводит к задержкам.
Для разбиения длинной синхронной задачи на части, чтобы не блокировать event loop, можно использовать рекурсию с `setImmediate` или `setTimeout(fn, 0)`. Каждая итерация будет планировать следующую как новую макрозадачу, позволяя циклу обрабатывать другие ожидающие задачи (например, запросы других клиентов) между итерациями.
Работа с модулями в Node.js
В этом разделе рассматриваются системы модулей в Node.js: CommonJS (устаревшая, но широко используемая) и ECMAScript Modules (ESM) (современный стандарт).
Современный стандарт в Node.js — это ECMAScript Modules (ESM) с ключевыми словами `import` и `export`. Для их использования необходимо установить `"type": "module"` в файле package.json или использовать расширение файла `.mjs`. Старая система — CommonJS с `require()` и `module.exports`.
Node.js имеет набор встроенных (core) модулей, которые не нужно устанавливать отдельно. Примеры: `http` для создания сервера, `fs` для работы с файловой системой, `path` для работы с путями. Они импортируются без указания пути (например, `import fs from 'fs'`).
При импорте в ES Modules рекомендуется указывать полный путь к файлу, включая расширение (например, `import { myFunc } from './my-file.js'`). Без расширения или с неполным путем поведение может быть неоднозначным (файл или папка?), что является одним из недостатков дизайна модулей в Node.js.
Создание простого веб-сервера и его особенности
В этом разделе рассматривается создание базового HTTP-сервера с использованием встроенного модуля `http`, а также специфика обработки запросов от клиентов.
Для создания веб-сервера используется встроенный модуль http. Метод `createServer` возвращает сервер, который начинает слушать указанный порт с помощью метода `listen`. Важно: сервер будет работать постоянно, так как он создает активную макрозадачу (прослушивание порта), не давая event loop опустеть.
Общая переменная, объявленная в корне скрипта сервера, будет единой для всех подключений. Например, счетчик посещений будет увеличиваться для каждого клиента. В PHP для такого поведения пришлось бы использовать базу данных или Redis, так как каждый запрос обрабатывается в изолированном процессе. Это ключевая особенность Node.js.
Асинхронные вычисления и модуль Worker Threads
В этом разделе рассматривается модуль `worker_threads` для выноса тяжелых синхронных вычислений в отдельные потоки, чтобы не блокировать основной event loop.
Модуль worker_threads позволяет создавать изолированные потоки (воркеры) для выполнения тяжелых синхронных задач на других ядрах процессора. Основной поток и воркер могут обмениваться сообщениями через событийную модель (`postMessage`, `on('message')`). Это не панацея, но может помочь в определенных сценариях.
Более надежной альтернативой выносу тяжелых задач в отдельные потоки является использование систем очередей. Например, добавить задачу в базу данных, а отдельный процесс (например, по крону или через PM2) будет забирать их из очереди и выполнять последовательно или в ограниченном количестве. Это предотвращает перегрузку сервера в пиковые нагрузки.
Среда выполнения Node.js и браузерный JavaScript
В этом разделе рассматриваются базовые концепции платформы Node.js, ее отличия от браузерного JavaScript и сравнение с другими серверными технологиями, такими как PHP.
Ключевое отличие Node.js от браузерного JavaScript — среда выполнения. В браузере мы манипулируем DOM, а в Node.js создаем веб-серверы, обрабатываем запросы и работаем с файловой системой. Синтаксис языка остается тем же, но меняются цели и подходы.
Сравнение с PHP: В PHP для каждого запроса создается новый процесс, который стартует с чистого листа. В Node.js запускается один процесс, который обрабатывает все запросы в рамках одного event loop. Это позволяет легко создавать общие переменные и кэшировать данные в памяти между запросами, но требует осторожности с долгими синхронными операциями.
Цикл событий (Event Loop) и асинхронность
В этом разделе подробно разбирается механизм event loop, очереди макро- и микрозадач, а также принципы неблокирующего ввода-вывода в Node.js.
Основой асинхронности в Node.js является event loop. Он представляет собой бесконечный цикл, который выполняет задачи из очередей. Существует два типа задач: macro tasks (макрозадачи, например, setTimeout, setInterval, I/O) и micro tasks (микрозадачи, например, Promise). Сначала выполняется весь синхронный код, затем все микрозадачи, и только потом — макрозадача.
Программа на Node.js завершается, когда в event loop не остается активных macro tasks. Если в коде есть вызов setTimeout с колбэком, программа не завершится, пока не пройдет заданное время и колбэк не будет выполнен. Бесконечный цикл синхронного кода (while(true)) сделает программу вечно занятой и неспособной обрабатывать другие задачи.
Долгая синхронная вычислительная задача (например, цикл на миллиард итераций) блокирует event loop. Пока она выполняется, Node.js не может обрабатывать другие запросы клиентов или выполнять другие асинхронные операции. Все остальные клиенты будут вынуждены ждать завершения этой задачи, что приводит к задержкам.
Для разбиения длинной синхронной задачи на части, чтобы не блокировать event loop, можно использовать рекурсию с setImmediate или setTimeout(fn, 0). Каждая итерация будет планировать следующую как новую макрозадачу, позволяя циклу обрабатывать другие ожидающие задачи (например, запросы других клиентов) между итерациями.
Системы модулей: CommonJS и ESM
В этом разделе рассматриваются системы модулей в Node.js: CommonJS (устаревшая, но широко используемая) и ECMAScript Modules (ESM) (современный стандарт).
Современный стандарт в Node.js — это ECMAScript Modules (ESM) с ключевыми словами import и export. Для их использования необходимо установить "type": "module" в файле package.json или использовать расширение файла .mjs. Старая система — CommonJS с require() и module.exports.
Node.js имеет набор встроенных (core) модулей, которые не нужно устанавливать отдельно. Примеры: http для создания сервера, fs для работы с файловой системой, path для работы с путями. Они импортируются без указания пути (например, import fs from 'fs').
При импорте в ES Modules рекомендуется указывать полный путь к файлу, включая расширение (например, import { myFunc } from './my-file.js'). Без расширения или с неполным путем поведение может быть неоднозначным (файл или папка?), что является одним из недостатков дизайна модулей в Node.js.
Создание HTTP-сервера и обработка запросов
В этом разделе рассматривается создание базового HTTP-сервера с использованием встроенного модуля http, а также специфика обработки запросов от клиентов.
Для создания веб-сервера используется встроенный модуль http. Метод createServer возвращает сервер, который начинает слушать указанный порт с помощью метода listen. Важно: сервер будет работать постоянно, так как он создает активную макрозадачу (прослушивание порта), не давая event loop опустеть.
Общая переменная, объявленная в корне скрипта сервера, будет единой для всех подключений. Например, счетчик посещений будет увеличиваться для каждого клиента. В PHP для такого поведения пришлось бы использовать базу данных или Redis, так как каждый запрос обрабатывается в изолированном процессе. Это ключевая особенность Node.js.
Многопоточность и фоновые задачи
В этом разделе рассматривается модуль worker_threads для выноса тяжелых синхронных вычислений в отдельные потоки, а также альтернативные архитектурные подходы.
Модуль worker_threads позволяет создавать изолированные потоки (воркеры) для выполнения тяжелых синхронных задач на других ядрах процессора. Основной поток и воркер могут обмениваться сообщениями через событийную модель (postMessage, on('message')). Это не панацея, но может помочь в определенных сценариях.
Более надежной альтернативой выносу тяжелых задач в отдельные потоки является использование систем очередей. Например, добавить задачу в базу данных, а отдельный процесс (например, по крону или через PM2) будет забирать их из очереди и выполнять последовательно или в ограниченном количестве. Это предотвращает перегрузку сервера в пиковые нагрузки.
В чем заключается ключевое различие между использованием JavaScript в браузере и в среде Node.js?
В среде выполнения: в браузере мы работаем с DOM, а в Node.js создаем серверные приложения.
В Node.js нет объектов `window` или `document`. Вместо этого у нас есть глобальные объекты для работы с сервером, файловой системой (`fs`), сетью (`http`), что позволяет создавать веб-серверы и инструменты командной строки на JavaScript.
В синтаксисе языка и типах данных.
Почему в Node.js легко создать переменную, общую для всех пользователей сайта, в отличие от PHP?
Потому что в Node.js один процесс обрабатывает все запросы в рамках одного event loop, в отличие от PHP, где для каждого запроса создается новый процесс.
В PHP архитектура (например, модуль mod_php для Apache) предполагает запуск нового экземпляра приложения для каждого HTTP-запроса. В Node.js приложение стартует один раз, и все клиенты взаимодействуют с одним и тем же экземпляром, что делает общие переменные легко реализуемыми.
Потому что Node.js использует многопоточность, а PHP — однопоточную модель.
Что такое event loop в контексте Node.js?
Это бесконечный цикл, который управляет очередью асинхронных задач (macro и micro tasks) и обеспечивает неблокирующую асинхронную модель выполнения.
Event loop — это фундаментальная концепция, лежащая в основе асинхронности в JavaScript и Node.js. Он позволяет выполнять неблокирующие операции ввода-вывода, несмотря на то, что сам JavaScript является однопоточным. Цикл берет задачи из очереди по мере их готовности.
Это библиотека для работы с событиями в браузере.
Почему следующий код Node.js завершится не сразу, а через 3 секунды: setTimeout(() => console.log('Done'), 3000);
Потому что в event loop активна одна macro task (таймер), которая будет выполнена через 3 секунды, и только после этого цикл опустеет и программа завершится.