angular - "flatten"数组在 RxJS Observable 中的最佳方式

标签 angular rxjs rxjs5

我的后端经常以 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();

mergeMap(val => val) 行感觉不是很地道。

是否有更好的方法将转换应用于 Observable 发出的数组成员?

注意。我希望 RxJS 运算符(相对于数组方法)来转换我的项目,因为我需要能够将每个项目投影到第二个可观察对象中。典型用例:后端返回项目 ID 列表,我需要从后端请求所有这些项目。

最佳答案

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

dataFromBackend.pipe(
  tap(items => console.log(items)),
  mergeAll(), // or concatAll()
)

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

最终你也可以这样做:

mergeMap(val => from(val).pipe(
  tap(item => console.log(item)),
  map(item => item.name),
)),
toArray(),

2019 年 1 月:针对 RxJS 6 进行了更新

关于angular - "flatten"数组在 RxJS Observable 中的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42482705/

相关文章:

javascript - 使用 Observables 进行同步 http 请求

java - Angular 和 Java 应用程序在同一个域下运行

javascript - 合并两个可观察量,仅当其中一个可观察量完成而另一个未发出,或者两个可观察量都发出时才完成

javascript - 如何将 javascript 重新绑定(bind)到 angular2 组件中的元素?

javascript - 异常 : Cannot find a differ supporting object 'storeApps' in [apps in AppWidgetsComponent@8:28]

javascript - 意外的冷 Observable 行为

rxjs - 延迟 Rxjs BehaviorSubject 机制

javascript - Observable 最后订阅

html - Angular 8 : Send Form data as a Service to Another Component

angular - 如何在不重新查询服务器的情况下更新可观察数组中的对象?