Как я могу дать наблюдаемой трубе RxJS доступ к исходной эмиссии наблюдаемой И предыдущей эмиссии трубы? - PullRequest
0 голосов
/ 10 ноября 2018

У меня есть RxJS Observable, который генерирует серию изменений в базовой структуре данных, в частности, snapshotChanges () из AngularFirestoreCollection .

  • В настоящее время я сопоставляю это с массивом простых объектов JavaScript для использования моим приложением.
  • Этот массив никак не защищен, и использование кода может случайно изменить эту структуру.
  • Весь массив перестраивается всякий раз, когда издает исходный источник данных, даже если фактически изменился только один (или иногда нет) элемент в массиве.
  • Из-за этого все ссылки меняются каждый раз, что делает обнаружение изменений сложнее, чем нужно - и действительно замедляет мое приложение.

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

Что я не могу понять, так это как pipe() отключить наблюдаемую snapshotChanges() так, чтобы канал получил доступ к ранее выданным неизменяемым данным (или впервые по умолчанию) в дополнение к последний snapshotChanges() вывод.

В коде у меня уже есть следующее:

const docToObject = (doc) => { /* change document to fresh plain object every time */ };
const mappedData$ = snapshotChanges().pipe(
    map(changes => changes.map(change => docToObject(change.payload.doc)),
    tap(array => console.log('mutable array:', array)),
);

и я, по сути, ищу что-то вроде этого, где я не знаю, что XXX(...) должно быть:

const newImmutableObject = (changes, old) => {
  // new immutable structure from old one + changes, structurally sharing as much as
  // possible
};
const mappedData$ = snapshotChanges().pipe(

// ==================================================================================
    XXX(...), // missing ingredient to combine snapshotChanges and previously emitted
              // value, or default to []
// ==================================================================================

    map(([snapshotChanges, prevImmutableOutput]) => newImmutableOutput(...)),
    tap(array => console.log('IMMUTABLE ARRAY with shared structure:', array)),
);

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

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

1 Ответ

0 голосов
/ 10 ноября 2018

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

const newImmutableObject = (changes, old) => {
  // new immutable structure from old one + changes, structurally sharing as much as
  // possible
};
 const mappedData$ = snapshotChanges().pipe(
 scan((acc, current) => [...acc, current], []), //<-- scan is used here
 map(([snapshotChanges, prevImmutableOutput]) => newImmutableOutput(...)),
    tap(array => console.log('IMMUTABLE ARRAY with shared structure:', array)),
);
...