Реактивные сигналы
- title
- Реактивные сигналы
- type
- concept
- summary
- Реактивный примитив для автоматического распространения состояния, ставший доминирующей моделью в JS-фреймворках
- tags
- reactive-programming, signals, javascript, frontend
- created
- 2026-04-06
- updated
- 2026-04-06
- lang
- ru
- translation_of
- reactive-signals
- source_updated
- 2026-04-06
- translated
- 2026-09-01
- translator
- lllm/antigravity/gemini-3.7-flash-medium
Сигналы - это реактивный примитив, который хранит значение и автоматически уведомляет зависимые сущности при его изменении. Они стали доминирующей моделью реактивности в современных JavaScript-фреймворках, заменив или дополнив более старые подходы, такие как diffing виртуального DOM и потоки observable.
Как они работают
Сигнал оборачивает значение в геттер и сеттер. Чтение значения отслеживается, а запись в него инициирует уведомления. Вычисляемые значения (computed) подписываются автоматически, считывая сигналы во время своего вычисления - массивы зависимостей вручную указывать не требуется. В основе лежит алгоритм push-pull: сигналы активно (eagerly) проталкивают инвалидацию (помечая зависимости грязными), но зависимые сущности лениво (lazily) запрашивают новые значения только при чтении. Подробный разбор реализации см. в signal-push-pull-algorithm.
Зачем они нужны
Задача, которую решают сигналы, - синхронизация производного состояния с исходным без ручной связки. Электронные таблицы делают это естественным образом: изменилась ячейка - формулы пересчитались. Сигналы переносят ту же модель на состояние приложения.
Ранние подходы к реактивности в JavaScript имели свои компромиссы:
- Diffing виртуального DOM (React) заново рендерит целые поддеревья компонентов, полагаясь на мемоизацию, чтобы избежать лишней работы
- Потоки Observable (RxJS) мощны, но слишком многословны для простого производного состояния
- Ручные массивы зависимостей (хуки React) провоцируют ошибки: забытая зависимость приводит к устаревшим замыканиям (stale closures)
Сигналы автоматически отслеживают зависимости в момент чтения, обновляются с точечной гранулярностью (отдельные значения, а не деревья компонентов) и пропускают пересчёт, если результат никем не читается.
Внедрение во фреймворках
Solid был первым крупным фреймворком, полностью построенным на сигналах. ref() и computed() во Vue - это те же сигналы под другим названием. Preact добавил @preact/signals. Angular внедрил сигналы в v16. Руны в Svelte 5 компилируются в систему, подобную сигналам.
Стандартизация
Инициатива TC39 proposal-signals (Stage 1) предлагает добавить нативный примитив Signal в JavaScript. Тогда фреймворки смогут использовать общий уровень подписок и инвалидации, сохраняя при этом собственные API. См. tc39-proposal-signals.