我有一个RxJS Observable,它发出了对基础数据结构(特别是snapshotChanges() from an AngularFirestoreCollection)的一系列更改。
我想做的是使用Immer来维护一个不变的结构,以使未更改的数据在结构上与“新”数组共享。
我无法解决的问题是如何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)),
);
我觉得the expand
operator接近我的需要,但似乎只在后续运行中传递先前发出的值,而我还需要新发出的snapshotChanges
。
鉴于RxJS可观测管道,我如何在可观测管道的排放上进行操作,同时还能访问管道的先前排放?
答案 0 :(得分:1)
根据您的要求,我建议使用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)),
);