→Репо ←

Когда я впервые прочитал о Rx (в моем случае RxJS), мне было тяжело с Observables, Observers, держать их в чистоте, что они делают и т. д. и т. д. По общему признанию, я даже особо не игрался с RxJS. Однако я много читал об этом, всегда чувствуя, что просто понимаю, что происходит на самом деле.

Если потоки данных похожи на массивы, то остальное должно быть простым. Поскольку недавно я немного, но, казалось бы, прочно разобрался с Observables и Observers, я перешел к этому таинственному Rx.Subject. Это и Observable, и Observer? Что это хотя бы значит.

Это Observer и Observable

Оказывается, это именно то, что это означает. Это Observable и Observer вместе взятые. Он способен облегчить однонаправленный поток данных, поддерживаемый архитектурами, подобными React и Flux, или всем, что использует преимущества pub/sub. Когда обычные Observables, кажется, полагаются на внешний импульс для управления потоком данных через приложение, Rx.Subject управляет и направляет поток данных сам.

Один определяет Rx.Subject с аналогичной конечной целью и способом, подобным тому, как определяется Observable. Разработчик хочет каким-то образом формировать поток данных. С Observable это формирование сродни отображению функции на весь домен. Вы применяете преобразование ко всей группе данных. Rx.Subject также делает это, но вы также можете решить, как вы хотите поступить с конечным результатом. Здесь вступает в действие часть Observer.

var add = new Rx.Subject();
var store = [];
add.map( value => {
   store.push(value);
   return store; 
}).subscribe(val => { console.log(val); });
add.onNext(0);
// logs --> [0]
add.onNext(1);
// logs --> [0,1]

Код внутри «карты», который является «предварительной подпиской», — это то, как я решил преобразовать значение, передаваемое в Observer половину Rx.Subject через «onNext». Наблюдаемая половина Rx.Subject объясняется тем, что она обрабатывает данные как поток. Однако в этом случае источником потока данных является сам Субъект. Он прослушивает val и, когда он его получает, оперирует им, вставляя их в хранилище, а затем возвращая это хранилище.

onNext и Observer половина Subject

Часть, которая может сбить с толку незнакомого читателя, — это взаимодействие между этой функцией onNext и Subject. «onNext» — это метод наблюдателя, который катализирует действие потока данных, производимое субъектом «добавить» (действие — не технический термин, просто слово, которое я считаю подходящим). Точно так же, как Observable формирует форму потока данных, я определяю «наблюдаемую часть» с помощью карты. «map» — это просто метод, который работает с каждым элементом в последовательности. Если вы не используете Rx, вы можете использовать карту для выполнения преобразования каждого элемента в массиве. Поскольку Rx имеет дело с массивоподобными потоками данных, карта используется для выполнения операции над всем потоком. В моем случае я беру каждый элемент в потоке и вставляю его в хранилище.

Subject.map(x => { return x + 1; }).subscribe(val => { return val; });
//psuedo code-ish
for i in range(0,2)
   Subject.onNext(i)
   //--> 1
   //--> 2
   //--> 3

«val», возвращаемый субъектом, — это не то же самое, что «val», являющееся аргументом его метода «onNext», а его преобразованная версия. Вы можете сделать что-то очень похожее с Observable и анонимной функцией в качестве Observer, но в этом случае драйвером модификации является поток данных, проходящий случайно через цепочку Observables. В этом случае Субъект является независимым субъектом. Хотя его можно использовать так же, как Observables, он имеет больше возможностей как своего рода служебная функция для приложения. Я могу вызвать метод «onNext» объекта в любом месте, чтобы сделать что-то с потоком Observable, в то время как Observables, кажется, лучше служат основной опорой приложения.

Вариант использования магазина, который я придумал для Rx.Subject, ограниченная версия которого показана выше, очень хорошо подходит для Subject. Субъект «добавить» можно использовать в качестве моста между некоторым потоком данных Observable и состоянием приложения. Я очень рад продолжить использование Rx.Subject в будущем. Возможно, я мог бы даже реализовать более общую систему хранения состояний, используя все RxJS. С этой первой встречи я думаю, что смогу использовать Субъекты для многих небольших задач. Субъект может быть использован для всего, что связано со сбором и манипулированием отдельными данными. Как, например, получение строки из поля ввода и сброс внутреннего значения ввода в пустую строку, например:

const todoInput = document.getElementById('id');
const resetInput = new Rx.Subject();
resetInput
   .map( val => { return ""; })
   .subscribe( v => { 
      todoInput.value = v;
   });