需要结合两个不纯的可观察量

Need to combine two impure observables

我需要向将 return 过滤和未过滤数据的同一端点发出 2 个 AJAX 请求。然后我需要合并结果并在处理中使用它们。

    loadUnfilteredData() {
        // remember status
        const {status} = this.service.filters;
        delete this.service.filters.status;
        this.service.saleCounts$()
            .subscribe((appCounts) =>
                this.processUnfilteredData(appCounts)
            );
        // restore status
        if (status) {
            this.service.filters.status = status;
        }
    }

    loadFilteredData() {
        this.service.saleCounts$()
            .subscribe((appCounts) =>
                this.processFilteredData(appCounts)
            );
    }

问题是 this.service.saleCounts$() 是不纯的,而不是使用参数只是使用 this.service.filters。 这就是为什么我必须存储 status,然后将其从过滤器中删除,然后执行请求,然后恢复(因为其他请求使用相同的过滤器)。

所以我不能只combineLatest 处理两个可观察对象(因为我需要恢复)。

有什么解决办法吗?

(p.s。我知道这种方法很恶心,我知道状态管理和纯函数。只是想知道有没有漂亮的解决方案。

我相信你的约束要求这两个操作是 运行 顺序的,一个接一个,而不是像我们使用 combineLatest.[=22 时通常的情况那样并行=]

为了 运行 两个 Observable 顺序,我们可以使用 switchMap(作为现代 rxjs 中 pipe 调用中的运算符):

doFirstOperation()
    .pipe(
        switchMap(result => return doSecondOperation())
    );

一个潜在的问题是,当您 switchMap 访问 doSecondOperation 的结果时,您将无法访问 doFirstOperation 的结果。要解决这个问题,我们可以这样做:

doFirstOperation()
    .pipe(
        switchMap(firstResult => return doSecondOperation())
            .pipe(
                map(secondResult => [firstResult, secondResult])
            )
    );

即,使用 mapswitchMap 的返回值更改为包含两个值的数组。

将此与您对状态管理的“令人厌恶”的要求放在一起,您可以使用类似的东西:

  loadData() {
    const { status } = this.service.filters;
    delete this.service.filters.status;
    return this.service
      .saleCounts$()
      .pipe(
        finalize(() => {
          if (status) {
            this.service.filters.status = status;
          }
        }),
        switchMap(filteredData => {
          return this.service
            .saleCounts$() // unfiltered query
            .pipe(map(unfilteredData => [filteredData, unfilteredData]));
        })
      )
      .subscribe(results => {
        const [filteredData, unfilteredData] = results;
        this.processFilteredData(filteredData);
        this.processUnfilteredData(unfilteredData);
      });
  }

我认为没有多少人认为它很漂亮,但它至少能让你以一种看起来像你使用的方式获得结果 combineLatest,但可以解决你施加的限制不纯的方法。