Неправильные выводы

Снова пост о психологическо‑эзотерических открытиях. В прошлый раз рассказал, какие вопросы себе задаю, чтобы понять, что происходит в голове. Сегодня — как определяю, отвечаю я себе честно или нет.

Произношу ответ вслух

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

Поэтому я проговариваю диалог с собой в полный голос. Прям задаю себе вопрос, а потом отвечаю. Если в ответе слышу, что у меня неоправданно поменялась интонация, или в целом ответ звучит неубедительно, то где‑то я свернул не туда.

Об этом ещё Ильяхов писал когда‑то. Только там про пересушенный текст, а тут про честный ответ на вопрос.

Смотрю, не притягиваю ли я причины за уши

Способ посложнее — анализировать свои ответы. Не все причины, которые откапываются во время ответа, настоящие. Иногда мозг выдаёт красивую отговорку вместо настоящей причины. Но смысл анализа именно в том, чтобы докопаться до правды.

Обычно, когда я раскапываю настоящую причину, наступает ощущение «а, так вот оно что». Его можно сравнить с чувством, когда я не могу долго вспомнить какое‑то слово, а потом оно само всплывает в памяти.

Слежу, не возвращаюсь ли к этому вопросу

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

Есть два варианта: костыльнуть отговоркой или разобраться и пофиксить нормально. Костыли не сработают, я вернусь в ту же точку, откуда начал, просто время потеряю. Остаётся второй вариант.

Обсуждаю с другом

Друзья находятся в другом контексте, у них другой опыт, может даже другие взгляды на жизнь. Свежее мнение может направить меня в сторону, о которой я даже не думал до этого.

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

Обсуждаю с терапевтом

Не бойтесь обращаться за помощью — это нормально. Помощь не делает людей слабыми или больными. Стыдить кого‑то за обращение к терапевту так же глупо, как стыдить за обращение к стоматологу.

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

Это неприятно

Разбираться в этом вот всём вообще ни разу не весело. После первых результатов может даже отбить желание продолжать, потому что появится мысль «я живу эту жизнь как‑то не так».

Будет страшно возвращаться к собственным же вопросам. Но страх — это индикатор, «страх показывает, куда расти». И если страшно отвечать на вопрос, значит этот вопрос — важный.

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

Будет полезно

Санкт‑Петербург, август 2018

Летом Питер круче, чем зимой, конечно :–)

Из «чё посмотреть» могу порекомендовать Гранд‑макет:

Искусственная ночь на макете
Копия моста во Владивостоке
Относительный размер макета

Кайф — рассматривать детали. Очереди в Сбере:

Очереди в Сбербанке

Отсылки к картинам, фотографиям и фильмам:

Отсылка к «Охотникам на привале»
Отсылка к фотографии снежного человека
Отсылка к фильму «Прогулка»

Мемас про «менеджера, заказчика, проджекта и тебя»:

Все смотрят, один копает

В прошлый раз в Эрмитаж не удалось попасть, в этот — получилось:

Эрмитаж — 1
Эрмитаж — 2
Эрмитаж — 3
Эрмитаж — 4

Новая Голландия хороша. Удобные стулья, мягкий газон, не шумно:

Газон и стулья
Грунт закрыт, покрытие мягкое
Люди отдыхают

Приехать летом, погулять по Летнему саду — чек:

Летний сад — 1
Летний сад — 2

Без фотографий с набережных и мостов никак, конечно:

Дворцовая:

Дворцовая площадь

Невский:

Невский проспект

Маяковского:

Улица Маяковского вечером

Квадрат:

Квадратная арка
Мир

«Дао физики» Фритьофа Капры

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

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

Книга рассказывает о схожести современной физики и восточных философских концепций: даосизма, буддизма, индуизма.

Всё начинается с того, что автор приводит примеры, как западная цивилизация старательно разделяет чувственный опыт и рациональный:

В основе его [Рене Декарта] мировоззрения лежало фундаментальное разделение наших представлений об окружающем мире на две независимые сферы: сферу сознания и материальную. В результате ученые смогли рассматривать материю как нечто неживое и полностью независимое от них, а материальный мир — как огромную, сложную систему

…человеческий ум знает два способа познания, сознания: рациональный и интуитивный, — и они традиционно ассоциируются с наукой и религией соответственно

Но по мнению автора это не так продуктивно, как мы привыкли думать. Самое главное, что вредит в таком разделении — неточность наших знаний в итоге:

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

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

Уверенность в том, что наши абстрактные понятия об отдельных «вещах» и «событиях» отражают реалии нашего мира, — не более чем иллюзия

Все используемые нами для описания природы понятия ограничены; это не факты, а продукты нашего мышления — части нарисованной карты, а не реальной местности

Одна из самых трудных и в то же время самых важных задач при создании модели — определение границ ее применения… как только модель или теория начинает работать, следует задать себе такие вопросы: Почему она работает? Каковы ее ограничения? В чем именно состоит ее приблизительность?

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

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

Сейчас наблюдатель уже не может быть просто «наблюдателем», а становится «участником» события, за которым наблюдает. Поэтому и рациональный метод рано или поздно перестанет работать:

В атомной физике ученый не может играть роль объективного наблюдателя; он становится частью наблюдаемого мира… Джон Уилер… предлагает заменить слово «наблюдатель» словом «участник»

Однажды будет достигнута точка, где необъясненным элементом… окажется сам научный контекст. Далее теория не будет более способна выразить результаты словами или рациональными понятиями и… выйдет за пределы науки… Знание, содержащееся в таком видении, будет полным, но его невозможно будет выразить словами. Оно станет тем знанием, которое подразумевал Лао‑цзы… «Тот, кто знает, не говорит. Тот, кто говорит, не знает»

Потом книга показывает, как такое разделение повлияло на наш образ мышления:

Учение Декарта… сильно влияло на западную философию… «Мыслю, следовательно — существую» в западной культуре понималось так: человек отождествляет себя со своим разумом, а не всем организмом… И большинство людей воспринимают себя как отдельное эго, существующее «внутри» их тела

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

А затем автор обращается к чувственному опыту и показывает, что он — тоже важная часть знаний и непреодолимое ограничение в процессе познания:

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

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

[В даосизме] признавая относительность… норм морали, мудрец не стремится к добру… Он старается поддерживать динамическое равновесие между добром и злом

Автор часто указывает, как восточные философии отличаются от западного рационального метода познания:

Восточные мистики хотят подчеркнуть эмпирический характер своего знания… Стадия экспериментов в исследовании соответствует «прозрению» восточного мистика, а научные модели и теории — способам его интерпретации

Показывает, что без принятия чувственного опыта трудно выразить и воспринять то, что происходит вокруг:

Для простого человека существует парадоксальное противоречие: нам нужны слова, чтобы рассказать о своих внутренних ощущениях, которые по природе своей выходят за пределы языка

Перед тем, как начать рассказывать о самих концепциях, книга объясняет, в чём их цель и что они стараются донести:

Высочайшая их цель… — осознание единства и взаимосвязи всех вещей, преодоления ощущения обособленности и слияние с высшим бытием

Суть — осознание единства и взаимосвязанности вещей и явлений, восприятие всего как проявлений единства

Одна из высших целей человека в духовных традициях Востока — осознание того, что все противоположности полярны, а значит, образуют единство

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

…не означает, что мир — иллюзия. Обманчивы только наши мысли о том, что формы и структуры, вещи и события — реальные проявления природы. Это лишь цепочка понятий, при помощи которых мы мыслим, измеряя и классифицируя мир. Майя — наша иллюзия, возникающая при отождествлении понятий с реальностью, или карты местности — с самой местностью

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

О буддизме. Здесь я нашёл много пересечений с книгой «Тонкое искусство пофигизма»:

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

Первая Благородная Истина утверждает, что основная составляющая человеческого существования — страдания, порождающие разочарования. Разочарование коренится в нашем нежелании признать… что всё вокруг нас не вечно и преходяще

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

Вторая Благородная Истина разъясняет причину возникновения страданий —… «привязанности» или «жажды». Это бессмысленная привязанность к жизни, проистекающая из невежества

Согласно Третьей Благородной Истине, страдания и разочарования могут быть прекращены. Мы способны освободиться от уз кармы и достичь полного освобождения — нирваны

Четвертая Благородная Истина [призывает] следовать Благородному Восьмеричному Пути, который тоже ведет к достижению состояния Будды

Будда учил, что… прошлое, будущее, физическое пространство… и личность, всё это — лишь названия, формы мышления, общеупотребительные слова, попросту искусственная реальность

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

…учение дзен считает достоинством «отсутствие слов, объяснений, наставлений и знания» в своей философии. Учение сосредоточено только на достижении просветления, а толковать свой опыт его последователи не любят… «Заговаривая о чем‑то, ты теряешь нить»

Сиди спокойно и ничего не делай. Весна приходит и трава растет сама собой

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

Просветление здесь значит не удаление от мира, а активное участие в повседневных делах

Когда дзенского наставника Бо‑чжана попросили дать определение дзен, он сказал: «Когда голоден — ешь, когда устал — спи». Вроде бы просто и очевидно… но на самом деле это сложная задача

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

Сторонники даосизма в первую очередь интересовались созерцанием природы и постижением ее Пути, Дао. По мнению даосов, человек достигает счастья тогда, когда следует естественному порядку, действуя под влиянием импульсов и доверяя интуиции

Текучесть и изменчивость свойственны всему мирозданию… Мудрец стремится распознать [устойчивые модели мироздания] и действует в соответствии с ними. Он становится «человеком с Дао», живущим в гармонии с природой

Основной признак Дао — цикличность его движения и изменений

Основной ее посыл — идея о непрекращающихся превращениях и преобразованиях всего сущего

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

Они утверждают: если хочешь добиться чего‑либо, следует начать с его противоположности

Если Будда «так приходит и уходит», то даосский мудрец — тот, кто «течет… вместе с течением Дао»

Очень хорошо об изменениях, их причинах, как к ним относиться:

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

О сущности дао:

…уподобляет Дао долине между гор или сосуду, который всегда остается пустым, сохраняя способность содержать в себе всё бесконечное множество вещей

Ещё хорошо про озарение:

Мы порой забываем… какое‑то слово и не можем вспомнить его Оно «вертится на языке», но не соскочит с него, пока мы не сдадимся… И внезапно… мы вспоминаем… слово. Мышление при этом не включается. Это и есть неожиданное озарение. Оно особенно характерно для буддизма, согласно которому наша изначальная природа — природа просветленного Будды, и мы просто забыли ее

Ещё автор часто в лоб сравнивает современную физику и философии:

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

О словах и парадоксах:

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

О цикличности и преобразовании форм:

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

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

О полях и начале вещей:

После возникновения понятия поля физики стали стремиться к тому, чтобы объединить все поля в единое фундаментальное поле, в рамках которого можно было бы объяснить все физические явления… Такие понятия, как Брахман в индуизме, Дхармакайя в буддизме и Дао в даосизме, могут рассматриваться как эквивалент конечного объединенного поля, из которого берут начало… все явления вообще

В китайской философии идея поля присутствует уже в самом понятии Дао, которое, будучи пустым и бесформенным, порождает все формы

О частицах, как связующем звене между процессами преобразования:

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

Пространство и время полностью эквивалентны друг другу… Если мы хотим получить картину этого взаимодействия, то должны сделать четырехмерную «моментальную фотографию», отображающую интересующие нас временной промежуток и область пространства

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

Читается не так легко, как, например, то же «Тонкое искусство пофигизма», но если хочется посидеть пару вечеров и подумать над своими взглядами на мир, то рекомендую прочесть.

О чём стоит хотя бы немного знать перед тем, как начать читать:

  • О физике элементарных частиц и стандартной модели, без них будет туго осилить хардкорные главы. Мне помог непрофильный университетский курс.
  • Об истории буддизма, даосизма или индуизма. Хорошо, если вы знаете о том, как они зародились и когда, это даст больше контекста. Мне опять‑таки помог двусеместровый курс философии в университете.

Кроме самой книги я ещё посоветую:

Управление состоянием приложения с помощью конечного автомата

Конечный автомат — это модель системы, у которой есть конечное количество состояний и переходов между этими состояниями.

Звучит заумно, но всё это можно представить в виде лампочки. У неё есть два состояния: включена и выключена. Чтобы перевести лампочку из одного состояния в другое, мы подаём сигнал — нажимаем на кнопку включения. Тогда срабатывает переход, и состояние лампочки меняется.

Набор состояний и переходов между ними можно нарисовать в виде графа, где вершинами будут состояния, а рёбрами — переходы.

Граф состояний и переходов лампочки

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

Чё‑та сложна. В чём польза?

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

С конечным автоматом не возникает ситуации, когда «мы что‑то нажали, и всё исчезло». Потому что причинно‑следственные связи прописаны жёстко и не разбросаны по приложению в разных местах.

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

А ещё список переходов даёт возможность быстро нагенерировать кучу автотестов на изменения состояния.

Обзор тупого приложения для примера

Допустим, у нас есть приложение, которое загружает данные с сервера по нажатию на кнопку. (Работает в последнем Хроме, за другие браузеры не ручаюсь. В Сафари точно не работает.)

В этом приложении есть несколько состояний, которые отображаются на экране.

Тогда возможные переходы между состояниями:

  • с главной по нажатию на кнопку «загрузить» переходим в состояние загрузки;
  • из состояния загрузки попадаем в отображение данных, если всё ок;
  • либо в отображение ошибки, если что‑то не ок;
  • из отображения данных или ошибки можем попасть на главную по нажатию на кнопку «очистить»;
  • из отображения данных можем перейти в состояние загрузки, если нажмём на кнопку «загрузить ещё».

Если представить это дело в виде графа, то получится так: Граф состояний и переходов приложения из примера

Фейковое АПИ

Для эмуляции загрузки данных будем использовать джейсон‑плейсхолдер. Напишем небольшую функцию, которая будет запрашивать данные с сервера:

// api.js
const fetchPosts = async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts')
  const posts = await response.json()
  return posts
}

Состояния, переходы и сам автомат

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

// fsm/states.js
const states = {
  INITIAL: 'idle',
  LOADING: 'loading',
  SUCCESS: 'success',
  FAILURE: 'failure',
}

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

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

// fsm/transitions.js
const transitions = {
  [states.INITIAL]: {
    fetch: () => /* возвращает states.LOADING */,
  },

  [states.LOADING]: {},

  [states.SUCCESS]: {
    reload: () => /* возвращает states.LOADING */,
    clear: () => /* возвращает states.INITIAL */,
  },

  [states.FAILURE]: {
    retry: () => /* возвращает states.LOADING */,
    clear: () => /* возвращает states.INITIAL */,
  },
}

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

Метод stateOf будет показывать, в каком состоянии находится автомат сейчас. Приватный метод updateState будет обновлять состояние и данные, если требуется.

// fsm/machine.js
class StateMachine {
  constructor({ initial, states, transitions, data=null }) {
    this.transitions = transitions
    this.states = states
    this.state = initial
    this.data = data
  }

  stateOf() {
    return this.state
  }

  _updateState(newState, data=null) {
    this.state = newState
    this.data = data
  }
}

Запуск переходов

Чтобы можно было управлять переходами извне, создадим метод performTransition. Он будет принимать название перехода и проверять, возможен ли такой переход. Если возможен, то будет обновлять состояние.

// fsm/machine.js
performTransition(transitionName) {
  const possibleTransitions = this.transitions[this.state]
  const transition = possibleTransitions[transitionName]
  if (!transition) return

  // переход возвращает новое состояние для автомата
  const newState = transition()
  this._updateState(newState)
}

В теории всё просто: вот мы загружаем данные, значит переводим автомат в states.LOADING. Вот они загрузились, значит переводим в states.SUCCESS. Но на деле: как управлять потоком событий? как узнать, что данные действительно загрузились? как определить, что не произошла ошибка по пути?

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

Генераторы и асинхронные генераторы

Генератор — это функция, которая может приостанавливать своё выполнение и продолжать его позже. В основе работы генераторов лежат итераторы, поэтому любой генератор можно проитерировать через for…of.

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

function* transition() {
  yield states.LOADING
  yield states.SUCCESS
}

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

Чтобы получить данные из генератора, мы можем проитерировать его вручную:

const generator = transition()
generator.next() // { done: false, value: 'loading' }
generator.next() // { done: false, value: 'success' }
generator.next() // { done: true, value: undefined }

Либо через for…of:

for (const state of transition()) {
  console.log(state) 
}

Тогда если мы хотим применить подобный переход к автомату, то мы немного изменим метод performTransition:

// fsm/machine.js
performTransition(transitionName) {
  const possibleTransitions = this.transitions[this.state]
  const transition = possibleTransitions[transitionName]
  if (!transition) return

  // вот тут используем for ... of
  for (const state of transition()) {
    this._updateState(state)
  }
}

Но этого мало :–)
Ведь помимо нескольких состояний, у нас есть ещё и запрос на сервер, который надо обработать.

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

Асинхронный генератор почти не отличается от обычного, только вместо значений он выбрасывает промисы. И итерировать его придётся через for await…of:

// fsm/transitions.js
async function* transition() {
  yield states.LOADING

  try {
    const data = await fetchPosts()
    yield states.SUCCESS
  }
  catch(e) {
    yield states.FAILURE
  }
}

Так как генератор выбрасывает промисы, то чтобы их развернуть, нам и здесь понадобится await. Поэтому метод performTransition тоже становится асинхронным.

// fsm/machine.js
async performTransition(transitionName) {
  const possibleTransitions = this.transitions[this.state]
  const transition = possibleTransitions[transitionName]
  if (!transition) return

  for await (const newState of transition()) {
    this._updateState(newState)
  }
}

Не только состояние, но ещё и данные

Состояния мы теперь записываем и обрабатываем, но пока что никуда не записываем данные от сервера.

В автомате для этого у нас есть поле data. Будем его обновлять при получении данных из перехода если они есть:

// fsm/transitions.js
async function* transition() {
  yield {newState: states.LOADING}

  try {
    const data = await fetchPosts()
    yield {newState: states.SUCCESS, data}
  }
  catch(e) {
    yield {newState: states.FAILURE}
  }
}

И в performTransition соответственно записываем их в поле data:

// fsm/machine.js
async performTransition(transitionName) {
  const possibleTransitions = this.transitions[this.state]
  const transition = possibleTransitions[transitionName]
  if (!transition) return

  for await (const {newState, data=null} of transition()) {
    this._updateState(newState, data)
  }
}

Рендер интерфейса

Окей, теперь надо это как‑то отрисовать. Можно сюда вкорячить какой‑нибудь Реакт, но мы пишем всё с нуля, поэтому и отрисовщик напишем тоже свой.

Функция‑рендер будет принимать состояние автомата и данные, которые он содержит. По состоянию будет выбирать, какой шаблон надо отрисовывать. Если использовать Реакт, то не многое изменится: мы просто будем возвращать не строки, а компоненты.

// renderer.js
const render = (state, payload) => {
  switch (state) {
    case states.INITIAL:
      return `<div>...</div>`

    case states.LOADING:
      return `<div>...</div>`

    case states.FAILURE:
      return `<div>...</div>`

    case states.SUCCESS:
      return `<div>...</div>`

    default: return ''
  }
}

Использовать это будем так:

// index.js
const renderApp = (state, data) => {
  const html = render(state, data)
  document.getElementById('root').innerHTML = html
}

renderApp(states.INITIAL)

Да‑да, innerHTML лучше не использовать, приложение лучше полностью не перерисовывать. Но камон, этот пост не об этом :–)

Отрисовка изменений

Тот же рендер мы будем использовать и когда автомат будет менять своё состояние.

Чтобы отследить изменения, нам понадобится как‑то подписаться на обновления состояния. Создадим метод subscribe и чуть обновим updateState:

// fsm/machine.js
subscribe(event, callback) {
  if (event === 'update') this._onUpdate = callback || null
}

_updateState(newState, data=null) {
  this.state = newState
  this.data = data

  this._onUpdate 
    && this._onUpdate(newState, data)
}

Теперь создадим экземпляр автомата, и в subscribe передадим событие update, на которое подписываемся и колбек:

// index.js
const fsm = new StateMachine({
  states,
  transitions,
  initial: states.INITIAL,
})

fsm.subscribe('update', (state, data) =>
  renderApp(state, data))

И осталось повесить вызовы переходов на события, например — клики по кнопкам. Вызывать переходы будем методом performTransition:

// index.js
fsm.performTransition('fetch')

Кнопка «загрузить ещё»

Я сделал два разных способа загрузки данных: один перетирает старые данные из автомата, второй — добавляет новые к старым. Работают они через два разных перехода: loadMore и reload от состояния states.SUCCESS.

В этой статье это уже не поместится, но ссылку на исходники я оставлю, если интересно почитайте :–)

Но зачем писать с нуля

Конечно, писать с нуля это не надо. Есть куча библиотек, которые реализуют конечные автоматы. Например, вот:

Но если в чём‑то хочется разобраться нормально, то стоит сделать это с нуля. Просто для того, чтобы упереться в проблемы, которые библиотека решает, и начать понимать, зачем её вообще использовать и чем она поможет.

Ссылки по теме

В этот раз ссылок действительно много.

Статьи о конечных автоматах:

О генераторах и итераторах:

Библиотеки:

Материалы к статье:

Вопросы себе

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

О чём речь

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

Всё началось с простого, я стал задавать себе 3 вопроса, когда чувствовал себя неважно:

  • что я сейчас чувствую?
  • откуда это чувство взялось?
  • что с ним можно сделать?

Пример

Важно отвечать на них честно и полно. Как и в прошлый раз, дело следует доводить до конца и докапываться до настоящей причины. Например:

— Что я сейчас чувствую?
— Сильную усталость.
— Откуда она взялась?
— Работал 5 часов без перерыва.
— Ты и раньше, бывало, так работал. Почему устал сегодня, в чём разница?
— Ну… спал плохо, постоянно просыпался.
— Из‑за чего?
— Выпил много кофе вечером накануне.
— Что можно с этим сделать прямо сейчас?
— Сходить полежать полчаса с закрытыми глазами.
— Какие меры на будущее можно принять?
— Следить за тем, сколько кофе пью и когда ложусь спать.

В разговоре я не «отчитываю себя за проступок», а просто пытаюсь разобраться, что происходит и как это можно исправить. Иногда решение лежит на поверхности (пойти отдохнуть), но иногда к нему нужно идти дольше.

Как это работает

После такого диалога мозг как будто перестраивается. Он перестаёт противиться и принимает то состояние, в котором я нахожусь.

«Да, я могу быть чем‑то расстроен, так бывает и это нормально. Теперь надо начать это как‑то решать.»

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

Положительные эмоции

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

  • что я сейчас чувствую?
  • нравится ли мне это чувство?
  • откуда оно взялось?
  • надо ли что‑то с этим делать? что именно?

Иногда я не могу определить, нравится мне какое‑то чувство или нет. Тогда я просто наблюдаю за ним и пробую понять, как к нему отношусь.

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

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

И это входит в привычку

Сейчас эти вопросы тихо входят в привычку. Выработать её мне помогли две вещи.

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

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

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

Раньше ↓