Вы должны различать две вещи здесь:
- Синхронные функции как узла
fs.readFileSync
, fs.statSync
и т.д. Все эти функции имеют в своем названии в Sync
(*). Эти функции действительно синхронно и блокировка. Если вы их вызываете, вы блокируете цикл событий и убиваете производительность узла. Эти функции следует использовать только в сценарии инициализации сервера (или в сценариях командной строки).
- Библиотеки и инструменты, такие как волокна или streamline.js. Эти решения позволяют вам писать код в sync-style, но код, который вы пишете с ними, по-прежнему будет выполнять асинхронно. Они делают не блокируют цикл событий.
(*) require
также блокируется.
Метеор использует волокна. Его код написан в стиле синхронизации, но он не блокирует.
Победа не на стороне производительности (эти решения имеют свои собственные накладные расходы, поэтому они могут быть немного медленнее, но они также могут делать лучше, чем необработанные обратные вызовы по конкретным шаблонам кода, такие как кеширование). Победа и причина, по которой эти решения были разработаны, относятся к юзабилити: они позволяют вам писать код в стиле синхронизации, даже если вы вызываете асинхронные функции.
25 Jan 2017 редактировать: Я создал 3 г для иллюстрации неблокирующих волокон: fibers-does-not-block.js, fibers-sleep-sequential.js, fibers-sleep-parallel.js
"Они не блокируют цикл событий." Заявление вводит в заблуждение, поскольку волокна должны блокировать цикл событий в критических разделах. Разработчик должен решить, какие критические разделы и использовать волокна соответствующим образом. – ashim
@ashim. Это неправильно: волокна не имеют превентивного характера; контекстные переключатели между волокнами реализованы libcoro и полностью отделены от цикла событий. –
Я смущен. Если я делаю операции ввода/вывода внутри волокна, между командами fiber.run() fiber.yield(), остальная часть программы будет ждать, пока этот раздел кода не будет выполнен. Как он не блокирует? Я что-то не понимаю? – ashim