代码之家  ›  专栏  ›  技术社区  ›  Alex Peters

如何让RxJS observable管道访问原始observable的发射和管道以前的发射?

  •  1
  • Alex Peters  · 技术社区  · 7 年前

    我有一个RxJS Observable,它会对底层数据结构进行一系列更改,具体来说, snapshotChanges() from an AngularFirestoreCollection .

    • 我目前正在将其映射到一个普通JavaScript对象数组,供我的应用程序使用。
    • 只要底层数据源发出,即使阵列中只有一项(有时甚至没有)实际更改,也会重建整个阵列。

    我想做的是使用 Immer

    我搞不懂的是怎么做 pipe() 场外 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可观测管道,我如何操作该可观测管道的排放,同时也可以访问管道以前的排放?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Sunil Singh    7 年前

    根据您的要求,我建议使用 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)),
    );
    
    推荐文章