将rjxs map和flatten / reduce转换为flatMap

时间:2018-03-09 10:44:13

标签: javascript angular typescript rxjs rxjs5

我相信使用flatMap可以重构以下代码,但我似乎无法按需要使其工作。

我理解flatMap本质上是映射然后变平,这对我来说是完美的,因为我正在使用forkJoin,所以从getAutocompleteSuggestions()获取一系列响应。

我想在订阅时获得单个结果数组(这是下面代码生成的结果),但是将顶级映射更改为flatMap会将多个单个对象发送到订阅。如何用flatMap()更好地编写这段代码?

   const $resultsObservable: Observable<any> = Observable.of(query)
          .switchMap(q => this.getAutocompleteSuggestions(q))
          //tried changing the below to flatMap()
          .map(res => { 
            return res.map(resp => {
              const content = resp.content;
              content.map(result => this.someMethod(result));
              return content;
            })
            .reduce((flatArr, subArray) => flatArr.concat(subArray), []);
          });



  getAutocompleteSuggestions(query: string): Observable<any> {
    const subs$ = [];
    //... add some observables to $subs
    return Observable.forkJoin(...subs$);
  }

1 个答案:

答案 0 :(得分:1)

看起来RxJS flatMap和数组原型方法flatMap之间可能存在一些混淆。请注意,RxJS flatMap的目的不是为了压缩作为流主体的数组,而是将Obervables流展平为单个可观察对象。见SO帖子:

Why do we need to use flatMap?

  

...基本上,如果Observable表示一个可观察对象,该对象推送类型为T的值,则flatMap采用类型为T&#39;的函数。 - &GT; Observable作为其参数,并返回Observable。 map采用T&#39;类型的函数。 - &GT; T并返回Observable。

如果您希望代码更清晰,可以使用myArray.flatMap方法。这是使用数组flatMap方法解答您问题的潜在答案:

&#13;
&#13;
const $resultsObservable: Observable<any> = Observable.of(query)
  .switchMap(q => this.getAutocompleteSuggestions(q))
  // Flatmap on the array here because response is an array of arrays.
  // The RxJS flatMap does not deal with flattening arrays
  .map(res => res.flatMap(resp => {
    const content = resp.content;
    content.map(result => this.someMethod(result));
    return content;
  }));

getAutocompleteSuggestions(query: string): Observable < any > {
  const subs$ = [];
  //... add some observables to $subs
  return Observable.forkJoin(...subs$);
}
&#13;
&#13;
&#13;