如何给RxJS可观察管道访问原始可观察发射和管道先前的排放? [英] How can I give an RxJS observable pipe access to the original observable's emission AND the pipe's previous emission?
问题描述
我有一个RxJS Observable,它对基础数据结构进行了一系列更改-具体来说,
I have an RxJS Observable that emits a series of changes to an underlying data structure—specifically, snapshotChanges() from an AngularFirestoreCollection.
- 我目前正在将此映射到普通JavaScript对象数组,以供我的应用使用.
- 此数组不受任何保护,使用代码可能会意外修改此结构.
- 只要底层数据源发出,整个数组都会重建,即使实际上只有一个(有时甚至没有)更改.
- 因此,所有引用每次都会更改,从而使更改检测变得比实际需要更难,并且确实减慢了我的应用程序的速度.
我想做的是使用 Immer 来保持不变的结构,以使数据保持不变在结构上与新"阵列共享.
What I want to do instead is use Immer to maintain an immutable structure, such that unchanged data is structurally shared with the "new" array.
我无法解决的是如何观察到 snapshotChanges()
的 pipe()
,以便管道可以访问先前发出的不可变数据(或),以及最新的 snapshotChanges()
输出.
What I can't work out is how to pipe()
off the snapshotChanges()
observable such that the pipe gets access to the previously emitted immutable data (or a first-time default) in addition to the latest snapshotChanges()
output.
在代码中,我基本上已经有了:
In code, what I basically already have is this:
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(...)
应该是什么:
and I'm essentially looking for something like this, where I don't know what XXX(...)
should be:
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可观测管道,我如何在可观测管道的排放量上进行操作,同时还能访问管道的先前排放?
推荐答案
根据您的要求,我建议使用可以跟踪所有先前状态和新状态的 scan
运算符.
As per your requirement I would suggest to use scan
operator which can track all previous state and new state.
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)),
);
这篇关于如何给RxJS可观察管道访问原始可观察发射和管道先前的排放?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!