Ответ 1
Цикл событий
Цикл событий Node.js выполняется под одним потоком, это означает, что код приложения, который вы пишете, оценивается в одном потоке. Сам Nodejs использует множество потоков под libuv, но вам никогда не приходится иметь дело с ними при написании кода nodejs.
Каждый вызов, который включает вызов ввода/вывода, требует регистрации обратного вызова. Этот вызов также немедленно возвращается, это позволяет выполнять несколько операций ввода-вывода параллельно, не используя потоки в коде приложения. Как только операция ввода-вывода будет завершена, обратный вызов будет нажат на цикл событий. Он будет выполнен, как только все остальные обратные вызовы, которые будут помещены в цикл событий до его выполнения.
Существует несколько способов сделать базовые манипуляции с тем, как обратные вызовы добавляются в цикл событий. Обычно вам не нужны эти, но время от времени они могут быть полезны.
Ни в коем случае не будет два истинных параллельных пути выполнения, поэтому все операции по сути являются потокобезопасными. Обычно будет несколько асинхронных параллельных путей выполнения, которые управляются циклом события.
Ограничения
Из-за цикла событий node не нужно запускать новый поток для каждого входящего tcp-соединения. Это позволяет node обслуживать сотни тысяч запросов одновременно, пока вы не вычисляете первые 1000 простых чисел для каждого запроса.
Это также означает, что важно не выполнять интенсивные операции с ЦП, поскольку они будут блокировать цикл событий и предотвращать продолжение других асинхронных путей выполнения.
Также важно не использовать вариант sync
всех методов ввода-вывода, поскольку они также будут блокировать цикл событий.
Если вы хотите делать тяжелые вещи CPU, вы должны просто делегировать его другому процессу, который может выполнять операцию привязки к процессору более эффективно, или вы можете записать его как node native add on.
Подробнее о вариантах использования
Управляющий поток
Чтобы управлять написанием многих обратных вызовов, вы, вероятно, захотите использовать библиотеку потока управления. Я считаю, что в настоящее время это самая популярная библиотека, основанная на обратном вызове:
Я использовал обратные вызовы, и они в значительной степени сводили меня с ума, у меня было гораздо больше опыта с использованием Promises, bluebird - очень популярная и быстрая библиотека обещаний:
Я обнаружил, что это очень чувствительная тема в сообществе node (обратные вызовы vs promises), поэтому, во что бы то ни стало, используйте то, что, по вашему мнению, будет работать лучше всего для вас лично. Хорошая библиотека потока управления также должна давать вам трассировки стека асинхронного сканирования, это действительно важно для отладки.
Процесс Node.js завершится, когда последний обратный вызов в цикле событий завершит его путь выполнения и не зарегистрирует никаких других обратных вызовов.
Это не полное объяснение, я советую вам проверить следующий поток, он довольно обновлен: