惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
C
Check Point Blog
M
MIT News - Artificial intelligence
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
DataBreaches.Net
大猫的无限游戏
大猫的无限游戏
D
Docker
Last Week in AI
Last Week in AI
IT之家
IT之家
F
Fortinet All Blogs
A
About on SuperTechFans
P
Proofpoint News Feed
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
B
Blog RSS Feed
博客园_首页
月光博客
月光博客
博客园 - 司徒正美
Y
Y Combinator Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания
Тонус в реактивных системах
nin-jin · 2026-05-26 · via Все публикации подряд на Хабре

Тонус в реактивных системах

Уровень сложностиСредний

Время на прочтение3 мин

Охват и читатели4K

Аналитика

Перевод

Вы можете вычислять зависимые реактивные состояния как можно раньше, так и как можно позже, вплоть до отказа от вычислений, если это возможно.

🍔 Instant: Мгновенные реакции
⏰ Defer: Отложенные реакции
🦥 Lazy: Ленивые вычисления

🍔 Instant: Мгновенные реакции

В библиотеках, таких как RxJS, зависимые состояния пересчитываются сразу же при изменении зависимости. Если нужно изменить несколько состояний подряд, это может привести к ненужным вычислениям.

Кроме того, эти дополнительные промежуточные вычисления создают несогласованное состояние, частично рассчитанное на основе уже обновленных состояний и частично на основе еще не обновленных. А несогласованное состояние, даже временное, — очень опасная вещь. В лучшем случае пользователь заметит мерцания — визуальные сбои. В худшем — приложение будет работать некорректно и содержать различные ошибки.

⏰ Defer: Отложенные реакции

Чтобы избежать мерцаний, пересчет можно отложить, чтобы он выполнялся только один раз, независимо от того, сколько зависимостей обновилось.

Однако пересчет будет выполнен в любом случае, даже если результат нам не нужен.

🦥 Lazy: Ленивые вычисления

В моделях реактивности с отложенным вычислением возможно ленивое вычисление инвариантов — только в момент, когда зависимое состояние действительно требуется.

При изменении исходных состояний мы не вычисляем зависимые и даже не планируем их вычисление, а лишь помечаем их как устаревшие. И если впоследствии к ним обращаются, они начинают вычисляться.

Это и самый экономный подход, и самый согласованный, так как гарантирует, что при каждом обращении к состоянию результат будет актуальным. Именно поэтому в $mol_wire это является основным принципом работы: на уровне абстракций ты даже не замечаешь, что ресурсы тратятся не сразу, а только по мере необходимости.

Ленивость в $mol_wire

Рассмотрим простое приложение со стабилизированным состоянием сумматоров.

Подписчики сверху, издатели снизу. Стрелки показывают движение данных. Обычно приложение имеет один корень, который служит точкой старта.

При изменении любого состояния сразу, синхронно, все прямые зависимости помечаются как «устаревшие», а все косвенные — как «сомнительные».

Это необходимо, чтобы каждое состояние знало свой статус актуальности в любой момент. Всего таких статусов 4:

  • 🔴 stale (-1) — значение устарело и требует пересчёта (исходное состояние).

  • 🟡 doubt (-2) — среди косвенных зависимостей есть устаревшие значения, их нужно обновить.

  • 🟢 fresh (-3) — значение актуально и может быть возвращено сразу.

  • 🔵 final (-4) — значение больше не изменится (задача выполнена или атом уничтожен).

Статус хранится в поле cursor. Отрицательные значения кодируют текущий статус, а неотрицательные — что в данный момент вычисляется и ведётся учёт зависимостей. Положительное значение cursor означает, сколько издателей уже отслежено.

Распространение уведомлений об изменении статуса к корню приложения может быть ресурсоёмкой операцией, особенно если тысячи других зависят от одного условия. Но это разумная цена за гарантию согласованности.

Если сразу изменить другие состояния, цепочки уведомлений будут короче, так как они наткнутся на уже устаревший подграф.

Пока что мы изменили только статусы состояний. Если по какой-то причине мы захотим прочитать значение устаревшего или сомнительного состояния, вычисления начнутся только в этот момент.

Сначала происходит погружение через сомнительные к устаревшим, которые вычисляют новое значение. Если значение изменилось, все зависимости тоже становятся устаревшими и начинают обновляться. И так вычисления поднимаются к запрошенному значению. Или останавливаются где-то на полпути, и все состояния выше помечаются как актуальные.

Таким образом, несмотря на отложенные ленивые вычисления, мы можем в любой момент получить текущее значение любого состояния, согласованное со всеми косвенными зависимостями.

Наконец, даже если мы явно не запрашивали никакое состояние, происходит автоматическое отложенное обновление всех корней строго в том порядке, в котором они вычислялись изначально.

Это гарантирует, что даже если граф состояний перестраивается во время пересчёта (что случается довольно часто), ни одно состояние не будет просто отброшено после вычисления, так как состояние, влияющее на его существование, всегда будет вычислено раньше.

Поскольку пользователь всё равно не увидит результат чаще, чем с частотой кадров экрана, имеет смысл отложить автоматическое обновление состояний до следующего кадра анимации. Таким образом, все изменения состояний в одном кадре группируются и приводят к одному повторному рендеру. А все пересчёты происходят только при необходимости.

Интересная особенность использования кадров анимации в том, что когда интерфейс не виден, его рендеринг автоматически замораживается, не тратя ресурсы на невидимую работу. Однако некоторые задачи всё равно требуют работы в фоне. Их нужно запускать согласно нужному интервалу времени. Но об этом поговорим в другой раз.

А пока, подписывайтесь на что-нибудь, вступайте во что-то там, и держите руку на пульсе вот этого вот.