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

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
U
Unit 42
GbyAI
GbyAI
M
MIT News - Artificial intelligence
美团技术团队
罗磊的独立博客
雷峰网
雷峰网
量子位
博客园 - 【当耐特】
Last Week in AI
Last Week in AI
D
Docker
小众软件
小众软件
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
阮一峰的网络日志
阮一峰的网络日志
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
WordPress大学
WordPress大学
V
V2EX
博客园_首页
腾讯CDC
The Cloudflare Blog
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

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

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет 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 за минуты Опыт разработчика как экономика внимания
Детерминированность реактивных вычислений
Дмитрий Карловский · 2026-06-03 · via Все публикации подряд на Хабре

Детерминированность реактивных вычислений

Средний

3 мин

6.1K

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

📰 Subscribe: По времени подписки
🧨 Event: По времени возникновения события
📶 Deep: По глубине зависимости
👨‍💻 Code: По позиции в программе

📰 Subscribe: По времени подписки

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

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

Это типичная проблема большинства библиотек.

🧨 Event: По времени возникновения события

Предположим, нам удалось зафиксировать порядок подписок тем или иным способом. Однако есть еще один источник нестабильности — порядок действий.

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

📶 Deep: По глубине зависимости

Некоторые библиотеки используют так называемую топологическую сортировку графа, чтобы пересчитывать инварианты в оптимальном порядке — от менее зависимых к более зависимым.

В этом примере Post изменяется на тот, к которому у нас нет доступа. Сначала обновится содержимое страницы, что не только приведет к ненужным пересчетам, но и может вызвать ошибки или просто мусор в виде побочных эффектов. И только затем, при вычислении Page, выяснится, что PostPage должен быть полностью уничтожен, а вместо него должно отображаться сообщение об ошибке доступа Forbidden.

Обратите внимание, что существование Title и Body зависит от значения Page. Но сами значения Title и Body уже не зависят от значения Page. И наоборот, значение Page не зависит от значений Title и Body. То есть связь между ними не реактивна. Но она есть. И это уже связь между владельцем и имуществом. То есть значение Page владеет реактивными состояниями Title и Body и, следовательно, контролирует их жизненный цикл.

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

👨‍💻 Code: По позиции в программе

Предпочтительно, чтобы реакции всегда обрабатывались в порядке, соответствующем порядку инициализации. Это гарантирует, что владелец обновится раньше всего, чем он владеет.

Здесь сначала обновится Allow, затем Page, что приведет к потере PostPage и, как следствие, к уничтожению PostPage со всеми внутренними состояниями без их вычисления.

🐵 Стабильность порядка вычислений

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

Это кажется очевидным, но вы будете в ужасе, когда узнаете, что стабильность поведения почти никогда не гарантируется. В результате возможна ситуация, когда программист взял тот же код, открыл те же окна, ввел те же значения… но у пользователя возникает ошибка, а программист не может ее воспроизвести. И тогда начинается веселая отладка.

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

class App extends Object {
  
  @mem Post( next?: Post ) { return next } // mutable state

  @mem PostPage() { // object factory
    return PostPage.make({
      Post => this.Post()
    })
  }

  @mem Forbidden() { // object factory
    return Forbidden.make({})
  }

  @mem Allow() { // derived state
    return Guard( this.Post() )
  }

  @mem render() { // recursive side effect
    if( this.Allow() ) this.PostPage().render()
    else this.Forbidden().render()
  }
  
}

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

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