代码之家  ›  专栏  ›  技术社区  ›  gka

rxjs-过滤后组合内部观察值

  •  1
  • gka  · 技术社区  · 7 年前

    [
      "https://some-url.com/someData1.json",
      "https://some-url.com/someData2.json"
    ]
    

    每个JSON可以有以下架构:

    {
      "isValid": boolean,
      "data": string
    }
    

    我想得到所有数据的数组,这些数据的isValid设置为true

    backend.get(url)
        .pipe(
            mergeMap((urls: []) =>
                urls.map((url: string) =>
                    backend.get(url)
                        .pipe(
                            filter(response => response.isValid),
                            map(response => response.data)
                        )
                )
            ),
            combineAll()
        )
    

    当both.json将“isValid”设置为true时,我将得到包含这两个数据的数组。 但当其中一个将“isValid”设置为false observable时,就永远不会完成。

    我可以使用mergall而不是combineAll,但是我接收的是单个数据流,而不是所有数据的集合。

    有没有更好的方法过滤掉可见光?

    2 回复  |  直到 7 年前
        1
  •  1
  •   ggradnig    7 年前

    正如你所说,内在的可观察者从不发射,因为 filter 不转发 backend.get 可见的。在这种情况下,操作符订阅了可观察到的——在您的例子中 combineAll

    我要做的只是将过滤和映射移动到 通过提供项目功能,如:

    backend.get(url)
        .pipe(
            mergeMap((urls: string[]) =>
                urls.map((url: string) => backend.get(url))
            ),
            combineAll(responses =>
                responses
                    .filter(response => response.isValid)
                    .map(response => response.data)
            )
        )
    

    看看这对你是否有用;)

        2
  •  0
  •   Buggy    7 年前
    import { forkJoin, Observable } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    interface IRes {
      isValid: boolean;
      data: string;
    }
    
    interface IResValid {
      isValid: true;
      data: string;
    }
    
    function isValid(data: IRes): data is IResValid {
      return data.isValid;
    }
    
    const res1$: Observable<IRes> = backend.get(url1);
    const res2$: Observable<IRes> = backend.get(url2);
    
    // When all observables complete, emit the last emitted value from each.
    forkJoin([res1$, res2$])
      .pipe(map((results: IRes[]) => results.filter(isValid)))
      .subscribe((results: IResValid[]) => console.log(results));
    
    推荐文章