Интенсивное чтение «Философия потока данных переднего плана»

React.js Redux MobX RxJS

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

Эта статья является итоговой работой "Fron-end Data Flow Philosophy".

1. Введение

Когда пишу эту статью, это очень напряжно.Если что-то не так, пожалуйста, поправьте меня.

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

2 Интенсивное чтение

Во-первых, режим управления потоком данных делится на три популярных.

  • Функциональный, неизменный, схематизированный. Типичная реализация: Redux - просто воплощение справедливости.
  • Реактивный, отслеживание зависимостей. Типичная реализация: Mobx.
  • Отзывчивый, отличие от верхнего реализовано в виде потока. Типичная реализация: Rxjs, xstream.

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

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

2.1 Начиная с хронологического порядка

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

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

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

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

На самом деле, до того, как React стал популярным, за один шаг был создан фреймворк, вступивший в эру react + mobx, да, то естьavalon. Авалон тоже очень популярен, но чтобы фреймворк был успешным, он должен быть в нужное время, в нужном месте и у людей. вложил в объятия реакции.

Это может быть немного субъективно, но я думаю, что React может стать популярным в основном потому, что все думают, что это легковесный angular + наследует идею, основанную на данных, которая очень соответствует фону времени Подождите, в основном все, кто использовал angular последовал этой волне.

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

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

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

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

Когда постепенно появился mobx, автор сделал аналогичную библиотеку:dob. Основная мотивация заключается в том, что ощущения от mobx не идеальны. Для новых переменных назначения необходимо использовать некоторые API, такие как extendObservable. Я только что обнаружил, что браузер поддерживает прокси-сервер зрело. Поэтому почти все личные проекты автора имеют заменил мобкс на доб.

В этот период стал популярен и успешно используется vue, один из трех гигантов: Если «реагирование + mobx хорошо работает, почему бы не использовать vue?» Флаг меня тронул.

На данный момент интерфейс развился до такой степени, что его можно охарактеризовать как разнообразный.Typescript победил поток и почти стал новым js.После появления ember и clojurescript основные языки также выпустилиСкомпилированная реализация на jsКонстанта, Lu LUN - возобновила поддержку в Webassembly, автор React заброшенная яма JS создала новую языку.

Я написал один раньшеПредварительное понимание интенсивного чтения разума.

Фронтенды, которые могут следовать этому набору духовных крещений, воспитали в своих сердцах навык спокойствия.Ниша больше не будет порогом для пересечения зоны комфорта.Каково это изучать rxjs? (Шучу, в сообществе rxjs есть много мастеров, которые совершенствуются много лет) Итак, недавно rxjs снова уволили.

Поэтому с хронологической точки зрения мы можем интерпретировать эти три фреймворка в порядке redux — mobx — rxjs.

2.2 Что дает редукс

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

Конечно, с одной стороны, из-за ответственности времени существует инструмент управления глобальным состоянием, чтобы компенсировать локальный поток данных React. Самая важная причина заключается в том, что Redux имеет набор почти чистых позиционирований, то естьЧисто,прослеживаемый.

Почти все готово для этих двух слов. Первый шаг отРазделение побочных эффектов

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

В сообществе есть много решений для асинхронной поддержки redux, от redux-thunk до redux-saga, постепенно набирает популярность идея асинхронной изоляции, привносимая redux. При этом один за другим появляется и набор основанных на этом высокоуровневых фреймворков инкапсуляции, рекомендуется использовать один из них, напримерdva.

Второй шагРазрешить механизм «ссылки на объект», который препятствует возврату, перенес огромную идею неизменяемости на фронтенд. На этот раз все состояние не будет изменено, функция «машины времени» redux-dev-tools, основанная на этом, впечатляет.

Для конкретной реализации Immutable обратитесь к интенсивному чтению, написанному автором ранее:Интенсивное чтение совместного использования неизменяемых структур.

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

2.3 Что приносит mobx

mobx — это очень гибкая структура TFRP, ответвление FRP, которое делает FRP прозрачным и, можно сказать, автоматизированным.

От функционала (FP) до FRP, до TFRP отношения — это просто расширение, что не означает, что чем длиннее слово, тем лучше.

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

С определенной точки зрения, концепция mobx очень похожа на rxjs, например, все они говорят, какие у них потрясающие наблюдаемые объекты. Так что же такое наблюдаемое?

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

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

Но у этого паттерна есть скрытая опасность, он вызывает загрязнение чистых функций побочными эффектами, точно так же, как редукс объединяет действия и редукторы. В то же время прямая модификация реквизита также приведет к конфликтам с неизменяемым определением реквизита в реакции. Поэтому mobx позже дал решение действия, которое решило конфликт с react props, но не решило проблему того, что побочные эффекты не были принудительно разделены.

Автор считает, что побочные эффекты и мутабельность — это две разные вещи, связь между мутабельностью и побочными эффектами будет объяснена позже. То есть mobx не решает проблему побочных эффектов, это не значит, что TFRP не может отделить побочные эффекты, а mutable не обязательно совместим спрослеживаемыйКонфликты, такие как mobx-state-tree, подключаются к redux через mutable.

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

2.4 Что дает rxjs

rxjs это еще одна ветка FRP основанная на Event Stream, поэтому вид со вспомогательной роли, сравнение mobx, вроде не такой умный, но определение источника данных, и TFRP по сути другое, как и rxjs такие фреймворки могут быть практически любыми событие в источник передачи данных.

同时,rxjs 其对数据流处理能力非常强大,当我们把前端的一切都转为数据源后,剩下的一切都由无所不能的 rxjs 做数据转换,你会发现,副作用已经在数据源转换这一层完全隔离了,接下来会进入一个美妙的纯函数世界,最后输出到 dom driver 渲染,如果再加上虚拟 dom 的点缀,那岂不是。 .岂不就是cyclejs?

Еще одна вещь, которую следует упомянуть, rxjs очень эффективен в абстрагировании чистых функций потоков данных, поэтому основная задача внешнего интерфейса состоит в том, чтобы извлечь инструмент для преобразования побочных эффектов, таких как события, запросы, push-уведомления и т. д., в источники данных. Cyclejs является таким фреймворком: он предоставляет набор вышеупомянутых библиотек инструментов, а стыковка с dom увеличивает возможности виртуального dom.

rxjs предлагает новую перспективу для интерфейсных решений управления потоками данных.Его концепция вдохновлена ​​mobx, но идея решения проблем похожа на redux.

redux-observable, который интегрирует возможности обработки потоков данных rxjs в существующую структуру потоков данных,

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

Если redux-saga решает проблему асинхронности, то redux-observable устраняет побочные эффекты, предоставляя возможности обработки данных rxjs.

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

Мы не только связали redux, mobx и rxjs на временной шкале, но и обнаружили их внутренние связи, эти три идеи представляют собой сеть, сложно переплетенную.

2.5 Что можно стряхнуть?

Мы обнаружили, что REDUX и RXJS полностью изолируют побочные эффекты, потому что у них есть общие черты.Это абстракция внешних побочных эффектов.

Redux делает редюсер чистой функцией, выполняя побочные эффекты в действии и изолируя побочные эффекты от редуктора.

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

Только у mobx отсутствует слой абстракции побочных эффектовТаким образом, код написан более прохладно, чем redux и rxjs, но побочные эффекты смешиваются с чистыми функциями, поэтому она не работает.

Некоторые люди скажут, что mobx непосредственно изменяемые изменения объекта также являются причиной побочных эффектов, автор думает, что это так, и это не так, посмотрите на следующий код:

obj.a = 1

Этот код определенно изменчив в js? Не обязательно, и не обязательно в таких языках, как C++, которые могут перегружать операторы.setterСинтаксис не обязательно изменяет исходный объект, например,Object.definePropertyпереписатьobjобъектsetterмероприятие.

Таким образом, мы можем открыть дыру в мозгу через перегрузку операторов, поэтому изменчивый способ получения результатов неизменен. В моем блогеRedux использует изменяемые структуры данныхТам есть описание принципа и использования, а автор mobxmweststrateЭто сделано для того, чтобы опровергнуть те голоса, которые жалуются на отсутствие у mobx исторической ретроспективной способности redux:

autorun(() => {
  snapshots.push(Object.assign({}, obj))
})

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

Например, новая работа автора mobx:immerБлагодаря возможности метапрограммирования прокси,setterПереписано какObject.assign()Реализует преобразование изменяемого в неизменяемое.

авторыdob-reduxТак же через прокси звонитьImmutablejs.set()Реализует преобразование изменяемого в неизменяемое.

Нужен ли компоненту поток данных?

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

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

Для нормализации побочных эффектов я считаю более подходящим использовать rxjs.Во-первых, механизм событий очень похож на rxjs.Кроме того, promise можно вернуть только один раз, а потомresolve rejectЕсть два состояния, в то время как Observable может возвращаться несколько раз, а встроенного состояния нет, поэтому он может представлять состояние более гибко.

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

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

Лучше использовать vue, чтобы снова понять реакцию + mobx

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

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

Сначала посмотрите на рендеринг вида, будь то jsx или шаблон, он один и тот же и может трансформироваться друг в друга.

Глядя на изоляцию побочных эффектов, вообще говоря, фреймворк не решает эту проблему, поэтому, будь то любая комбинация react/ag/vue + redux/mobx/rxjs, в конце концов, вы не будете полагаться на предыдущий фреймворк для решения это, но используйте последний redux/mobx/rxjs для решения.

Наконец, взгляните на драйвер потока данных: разные платформы имеют разные встроенные методы. В React есть встроенные методы, подобные redux, в vue/angular — встроенные методы, подобные mobx, а в cyclejs — встроенные rxjs.

С этой точки зрения самым естественным является react + redux, а react + mobx — это как vue + redux, что выглядит не очень естественно. То есть react + mobx неудобен только тем, что по-другому управляется поток данных. Для рендеринга представления, изоляции побочных эффектов, эти два фактора не зависят от какой-либо комбинации.

С точки зрения управления потоком данных мы можем мыслить на более высоком уровне. Например, синтаксис react/vue/angular рассматривается как три спецификации DSL. Фактически его можно описать общим DSL и преобразовать в соответствующий DSL. подключается к разным фреймворкам (у Alibaba уже есть такая реализация). И этот DSL также может блокировать встроенную обработку потока данных кадра, например:

<button onClick={() => {
  setState(() => {
    data: {
      name: 'nick'
    }
  })
}}>
  {data.name}
</button>

Если мы преобразуем вышеупомянутый общий код JSX в общий DSL, мы будем использовать общий способ описания структуры и методов, и когда мы преобразуем его в конкретный код Rection / Vue / Angluar, он будет преобразован в реализацию соответствующих Встроенная схема потока данных.

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

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

3 Резюме

Недавно разобралсяgaea-editor- Веб-дизайнер, сделанный автором, переосмыслил механизм плагина и рассказал об этом.

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

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

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

Проще сделать так, чтобы пользовательский интерфейс имел общие возможности.gaea-editor использует метод слота для рендеринга пользовательского интерфейса, то есть любой плагин может быть встроен в слот пользовательского интерфейса с соответствующим именем, если он предоставляет имя, а плагин сам может объявить любое количество сокетов, в ядре также есть несколько встроенных сокетов. Таким образом, пользовательский интерфейс плагина является чрезвычайно мощным, и любой пользовательский интерфейс может быть заменен новым плагином, если объявлено то же имя.

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

@Connect
class CustomPlugin extends React.PureComponent {
  render() {
    // this.props.Actions, this.props.Stores
  }
}

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

По сути, это немного похоже на механизм таких плагинов, как webpack:

export default (context) => {}

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

больше думать

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

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

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

react-less-component — это попытка, но то, как этот чистый компонент уровня представления взаимодействует с инфраструктурой потока данных, все еще относительно невелико.

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

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

Оттуда до

В HTML5 есть два интересных тега:details, summary. Комбинируя, можно добитьсяdetailsСкрыто по умолчанию, нажмитеsummaryМожет быть переключенdetailsЭффект следующий:

<details>
  <summary>标题</summary> 
  <p>内容</p> 
</details>

Это может быть переопределено css и полностью реализованоcollapseЭффект компонента.

detailsОн также предоставляет разработчикам только CSS через собственное внутреннее состояние браузера.

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

Некоторые люди скажут, как наделить компоненты верхнего уровня бизнес-значением? Не забывайте компоненты HTML. Эта спецификация может стать очень ослепительной после того, как в браузере будет реализовано большое количество нативных компонентов. DSL больше не нужен. HTML сам по себе является набором общего DSL, и фреймворк не нужен. Браузер имеет встроенный набор фреймворков.

В качестве отступления, все компоненты разрабатываются через html компоненты, что действительно реализует фреймворк сглаживания, в дальнейшем нет необходимости во фронтенд фреймворке, и нет необходимости во взаимном преобразовании react в vue. скорость компонентов повышается на порядок, а загрузка динамических компонентов может быть только незначительной. Вам нужно динамически загружать CSS, и вам не нужно беспокоиться о том, что компоненты, разработанные в разных средах/фреймворках, не могут сосуществовать. Front-end разработка — это всегда два шага вперед и один шаг назад.Не формируйте образ мышления.Время от времени вам нужно пересматривать старую технологию.

Тема отодвинута, реализовано из браузераdetailsС точки зрения метки внутри должен быть механизм состояния.Если этот механизм состояния может быть предоставлен разработчикам, обработка данных потока данных, изоляция побочных эффектов и внедрение зависимостей может выполняться браузером для нас, а избыточность и mobx сразу потеряют свои преимущества. , самый большой потенциал в будущем может быть у rxjs с мощными возможностями обработки потока данных чистой функции.

Конечно, в 2018 году redux и mobx по-прежнему сохранят сильную жизнеспособность.Даже в будущем, со встроенным механизмом потока данных браузеров, rxjs может не подходить для масштабной командной работы, особенно когда есть много нефронтальных конечная работа неполный рабочий день front-end.

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

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

Еще 4 обсуждения

Адрес обсуждения:Интенсивное чтение «Философия внешнего потока данных» · Выпуск № 58 · dt-fe/weekly

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