Комментарии 36
Вот так легко и непринужденно
function sayHello() { alert('Привет, ' + localStorage.name + '!'); }
растянулся на 28 строк кода :) +18
Спасибо большое за публикацию!
Понравился ваш стиль повествования — тема развивается очень гармонично,
читается ясно и просто, вопросы по ходу раскрываются.
Пишите еще про frp, с удовольствием ознакомлюсь.
Понравился ваш стиль повествования — тема развивается очень гармонично,
читается ясно и просто, вопросы по ходу раскрываются.
Пишите еще про frp, с удовольствием ознакомлюсь.
+3
> 5. Асинхронность
д) почему бы атому не вернуть deferred/promise, очевидный и родной для асинхронщины?
д) почему бы атому не вернуть deferred/promise, очевидный и родной для асинхронщины?
+1
Потому что promise — это, по сути, тоже атом, но способный сменить состояние только 1 раз. Смысл возвращать один атом из другого?
Если вернуть promise — то вызывающий код будет вынужден подписаться аж на два события — во-первых, событие change атома — а во-вторых, событие done обещания. Это точно будет удобно?
Если вернуть promise — то вызывающий код будет вынужден подписаться аж на два события — во-первых, событие change атома — а во-вторых, событие done обещания. Это точно будет удобно?
+2
Достаточно будет только done обещания.
Ну и, пожалуй, это будет удобнее, чем дефолтное значение/закэшированное/undefined/исключение, после котрых всё либо приходит в неконсистентность, либо нужно догадываться совершать дополнительные действия.
Ну и, пожалуй, это будет удобнее, чем дефолтное значение/закэшированное/undefined/исключение, после котрых всё либо приходит в неконсистентность, либо нужно догадываться совершать дополнительные действия.
0
Если done обещания нам достаточно, то зачем нам вообще атомы? Использовать атомы бессмысленно, если не подписываться на change, прямо или косвенно (через автотрекинг).
+1
Не нужно никаких действий. Вся технология рассчитана на то, что атомы могут меняться сами в зависимости от тех или иных неизвестных нам причин. Так какая, нафиг, разница: изменил пользователь своё имя сам или строка с его именем «Вася Пупкин» пришла, наконец-таки, из облака? Любая программа обрабатывающая первую проблему (а для решения её, напомним, и созданы атомы) автоматически способна решить вторую (обратное неверно).
+1
1. Атом — обобщение над обещаниями, так что ничто не мешает ему поддерживать их интерфейс. Для интеграции с императивным кодом это действительно удобно.
2. Атом абстрагирует от асинхронщины, позволяя в любой момент прервать вычисление не потеряв проделанной работы, а потом продолжить, когда нужные данные появятся, не начиная всё с начала.
2. Атом абстрагирует от асинхронщины, позволяя в любой момент прервать вычисление не потеряв проделанной работы, а потом продолжить, когда нужные данные появятся, не начиная всё с начала.
+2
*deleted*
0
Спасибо, интересно!
А если последовательно отделять функциональную (повторяющуюся) логику от бизнес-логики — код несколько упрощается. Я к тому, что дополнительный слой иерархии в «атомах», если его вести честно, делает жизнь намного проще.
И, что интересно, кода получается меньше. Прям намного меньше.
А если последовательно отделять функциональную (повторяющуюся) логику от бизнес-логики — код несколько упрощается. Я к тому, что дополнительный слой иерархии в «атомах», если его вести честно, делает жизнь намного проще.
И, что интересно, кода получается меньше. Прям намного меньше.
+1
Теперь я знаю, как называется тот подход, который я применяю уже пару лет)
На самом деле, это совершенно замечательный паттерн для работы с данными в сложносвязных системах. В своей практике использую его для построения слоя доступа к данным, т.е. как обертку для серверными API. Например, если в spa у нас есть возможность работать как незалогиненным, так и в рамках конкретного пользователя, то атомы это идеальный способ описать состояние логина системы. Аналогично, это очень хорошо работает для всех долгоживущих данных.
Но атомы не отменяют события и промисы. Если есть необходимость просто получить данные, то атомы избыточны и даже вредны.
На самом деле, это совершенно замечательный паттерн для работы с данными в сложносвязных системах. В своей практике использую его для построения слоя доступа к данным, т.е. как обертку для серверными API. Например, если в spa у нас есть возможность работать как незалогиненным, так и в рамках конкретного пользователя, то атомы это идеальный способ описать состояние логина системы. Аналогично, это очень хорошо работает для всех долгоживущих данных.
Но атомы не отменяют события и промисы. Если есть необходимость просто получить данные, то атомы избыточны и даже вредны.
0
По моему опыту «просто получить данные» — достаточно редкий случай. Обычно надо не просто получить, но и закешировать. А если закешировали, то и вовремя инвалидировать кэш, а потом снова грузить. Так что обещания использовать нет никакого смысла, если есть возможность использовать атомы.
0
Это очень сильно зависит от задачи, на самом деле. Грубо говоря, данные можно поделить на 2 категории: доменные, которые живут постоянно и описываются атомами, и контекстно-зависимые. Соотношение очень сильно зависит от типа системы. В корпоративном приложении или b2c системах, типа яндекс денег, практически не будет контекстных данных. В соц. сетях, наоборот, 90% времени это просмотр чужих страниц, котиков и т.п., которые существуют только в рамках текущего запроса пользователя. Их просто бессмысленно кэшировать и, более того, это прямой путь к неработоспособности на слабых клиентах. В любом случае, тут разумно использовать совершенно другие механизмы кэширования с меньшими издержками по памяти и производительности.
0
Я бы не разделял эти две категории. В любой соц сети есть навигация, чаты под каждым котиком, отображение лайков в реальном времени, куча разнообразных кнопочек: пожаловаться, удалить из ленты, восстановить, приглушить свет на всём сайте, кроме этой фоточки и тд и тп. И это всё состояния. А кэш — это лишь частный случай состояния, которое может очищаться, когда ничего зависимого от него не отображается на экране.
0
Мы с вами немного про разные вещи говорим.
Вы про UI, я про обертку над API. По сути, с вами согласен, если говорить именно про UI слой.
Вы про UI, я про обертку над API. По сути, с вами согласен, если говорить именно про UI слой.
0
Поняв проблему легко и придумать решение: достаточно при линковке атомов запоминать максимальную глубину среди ведущих плюс один, а при итерировании по отложенным для обновления атомам в первую очередь обновлять атомы с меньшей глубиной.Начав ради интереса делать свою реализацию под C#, я столкнулся с такой проблемой: при смене списка зависимостей в результате работы автотрекинга может измениться глубина. На уменьшение глубины можно забить, а вот увеличение глубины надо распространять всем мастерам вверх по графу. В итоге, мы возвращаемся к той же самой проблеме, с которой и начинали: глубина может обновляться много раз у одного и того же атома. Конечно, операция обновления глубины более дешевая, чем операция пересчета состояния атома (поскольку вторая может и запрос на сервер выполнять) — но все равно лишние квадраты в алгоритмах мне не нравятся.
К счастью, решение я нашел очень простое, не требующее существенной переделки архитектуры и даже упрощающее код: надо глубину вычислять не при линковке, а непосредственно при помещении атома в очередь.
0
Видимо я плохо осветил этот момент. Глубина может измениться и как правило это делает, но это не важно, пока атом не помещается в очередь на обновление. А он туда не помещается, поскольку только что актуализировал своё состояние. И все атомы меньшей глубины тоже его актуализировали. Так что следующий атом в очереди может смело вычислять своё значение и быть уверенным, что атомы с меньшей глубиной не изменятся, если он конечно сам не полезет их зачем-то менять.
0
То есть вы тоже вычисляете глубину в момент помещения атома в очередь?
0
Нет, в момент линковки ведомый спрашивает у ведущего его глубину и сравнивает со своей.Если своя глубина не больше глубины ведущего, то устанавливается на 1 больше, чем у него. А при помещении в очередь атом ставится в очередь соответствующей своей глубине на момент помещения.
0
Вспомнился доклад про кложуру.
+3
К сожалению из-за искромётной подачи, мало кто вникает в суть доклада: www.youtube.com/watch?v=R4sTvHXkToQ
0
Спасибо!
0
> Для описанного выше случая атом A пересчитает своё значение ровно один раз причём сделает это по окончании текущего обработчика события, то есть после всех внеснных нами изменений в атомы B, C и любые другие.
Получается, что в текущем обработчике мы не сможем использовать атом А, т. к. он будет иметь значение, не согласованное с В и С. Или всё-таки нет?
Получается, что в текущем обработчике мы не сможем использовать атом А, т. к. он будет иметь значение, не согласованное с В и С. Или всё-таки нет?
0
Если нам надо использовать значение ровно одного атома — то оно всегда будет согласовано с самим собой. Если же нам надо использовать значения нескольких атомов — то надо делать новый атом, использующий те значения — и возвращающий ровно одно. Этот атом будет обновляться только в те моменты времени, когда его входы будут согласованы — ну а вызывающий код вернулся к случаю номер 1.
Тут возможна вторая проблема — в случае автотрекинга зависимостей, атом может обратиться к другому атому, к которому он не обращался раньше — и состояние которого еще не согласовано с остальными входами. В таком случае надо не отдавать старое значение — а дождаться пока запрошенный атом довычислится. Посмотрим, удалось ли автору справиться с этим случаем. Мне вот, к примеру, в своей библиотеке этого сделать не удалось…
Тут возможна вторая проблема — в случае автотрекинга зависимостей, атом может обратиться к другому атому, к которому он не обращался раньше — и состояние которого еще не согласовано с остальными входами. В таком случае надо не отдавать старое значение — а дождаться пока запрошенный атом довычислится. Посмотрим, удалось ли автору справиться с этим случаем. Мне вот, к примеру, в своей библиотеке этого сделать не удалось…
0
Он будет помечен как «не актуальный», а значит при обращении актуализирует своё значение на основе B и C. Тут есть более сложный случай: D зависит от А, А только что запланировал к обновиться, а значит D ещё не знает, что ему тоже потребуется обновление (а может и не потребуется, А-то ещё не вычислился). Поэтому, если мы тут же обратимся к D, то получим старое значение, которое вскоре возможно(!) изменится.
0
Если у нас есть статус «не актуальный», то логично его продвигать вверх по иерархии до конца. То есть, если у нас A зависит от B и C, а D зависит от A, то при изменении B не актуальными должны становиться и A и D.
А что, действительно реальна ситуация, когда обновляются 2000 атомов, от которых зависит 2001-й?
А что, действительно реальна ситуация, когда обновляются 2000 атомов, от которых зависит 2001-й?
0
Тогда у нас получится что на каждый чих у нас будет обновляться всё приложение, что гораздо хуже.
Конечно, выводим список на 2000 элементов с фильтрацией по какому-либо параметру — получаем одну зависимость от самого списка и 2000 зависимостей от соответствующего параметра каждого из элементов. При изменении параметра у любого из элементов список перефильтруется. Это может показаться расточительным, ведь можно просто проверить подходит изменившийся элемент под фильтр и либо добавить, либо удалить. Но когда к фильтрации добавляется сортировка, группировка, да ещё и иерархия с разворачиванием ветвей и дублированием узлов, то задача «поместить в нужное место списка» становится неоправданно сложной.
Конечно, выводим список на 2000 элементов с фильтрацией по какому-либо параметру — получаем одну зависимость от самого списка и 2000 зависимостей от соответствующего параметра каждого из элементов. При изменении параметра у любого из элементов список перефильтруется. Это может показаться расточительным, ведь можно просто проверить подходит изменившийся элемент под фильтр и либо добавить, либо удалить. Но когда к фильтрации добавляется сортировка, группировка, да ещё и иерархия с разворачиванием ветвей и дублированием узлов, то задача «поместить в нужное место списка» становится неоправданно сложной.
0
> Так как чуть ли не каждый слот памяти заворачивается в атом, то реализация атомов должна быть максимально быстрой и компактной.
Сразу напомнило Datomic — это очень приятная база данных, похожая на RDF, OrientDB или Node4j — только с ещё более простыми и фундаментальными концепциями
Сразу напомнило Datomic — это очень приятная база данных, похожая на RDF, OrientDB или Node4j — только с ещё более простыми и фундаментальными концепциями
0
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.
Атом — минимальный кирпичик реактивного приложения