在RxJS Observable中"展平"数组的最佳方法

Ang*_*hef 34 rxjs rxjs5 angular

我的后端经常将数据作为数组返回到RxJS 5 Observable中(我使用的是Angular 2).

我经常发现自己想要使用RxJS运算符单独处理数组项,我使用以下代码(JSBin)执行此操作:

const dataFromBackend = Rx.Observable.of([
  { name: 'item1', active: true },
  { name: 'item2', active: false },
  { name: 'item3', active: true }
]);

dataFromBackend
  // At this point, the obs emits a SINGLE array of items
  .do(items => console.log(items))
  // I flatten the array so that the obs emits each item INDIVIDUALLY
  .mergeMap(val => val)
  // At this point, the obs emits each item individually
  .do(item => console.log(item))
  // I can keep transforming each item using RxJS operators.
  // Most likely, I will project the item into another obs with mergeMap()
  .map(item => item.name)
  // When I'm done transforming the items, I gather them in a single array again
  .toArray()
  .subscribe();
Run Code Online (Sandbox Code Playgroud)

mergeMap(val => val)条线感觉不是很惯用.

有没有更好的方法将变换应用于由Observable发出的数组成员?

NB.我希望RxJS运算符(vs数组方法)转换我的项目,因为我需要能够将每个项目投影到第二个observable.典型用例:项目ID列表的后端返回,我需要从后端请求所有这些项目.

mar*_*tin 34

您可以使用concatAll()mergeAll()不使用任何参数.

dataFromBackend.pipe(
  tap(items => console.log(items)),
  mergeAll(), // or concatAll()
)
Run Code Online (Sandbox Code Playgroud)

这个(包括mergeMap)仅适用于RxJS 5,因为它以相同的方式处理Observable,数组,类数组对象,Promises等.

最后你也可以这样做:

mergeMap(val => from(val).pipe(
  tap(item => console.log(item)),
  map(item => item.name),
)),
toArray(),
Run Code Online (Sandbox Code Playgroud)

2019年1月:更新了RxJS 6

  • @AngularFrance由于您正在解压缩数组,因此使用哪一个并不重要,两者都会产生有序的项目.这仅在与异步操作一起使用时才是相关的,而不是这种情况. (3认同)

小智 5

实际上,如果您在流中需要它,只需使用它:

.flatMap(items => of(...items))
Run Code Online (Sandbox Code Playgroud)

  • 请注意,现在它被称为“mergeMap”,而不是“flatMap” (2认同)

eng*_*ete 5

角 6 注释。

如果您用作可管道操作符,则 do 称为 tap!

https://www.learnrxjs.io/operators/utility/do.html 这是一个例子。

// RxJS 
import { tap, map, of, mergeMap} from 'rxjs/operators';

backendSource
  .pipe(
   tap(items => console.log(items)),
   mergeMap(item => item ),
   map(item => console.log(item.property))
  );
Run Code Online (Sandbox Code Playgroud)

  • 另一个提示:错误和完成有两个额外的参数 - 所以你也可以记录这些 (2认同)