繁体   English   中英

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

[英]Best way to “flatten” an array inside an RxJS Observable

我的后端经常将数据作为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 运算符(与数组方法)来转换我的项目,因为我需要能够将每个项目投影到第二个 observable 中。 典型用例:后端返回项目 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 更新

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

.flatMap(items => of(...items))

角 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))
  );

如果是同步操作,我建议使用 javascript 的Array.map代替,它甚至应该为您节省一些性能:

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

dataFromBackend
  .map(items => items.map(item => item.name))
  .subscribe();

我有一个类似的问题:

下列

  • 在每个项目上运行,
  • 拔出一个深层嵌套的对象
  • 将服务器响应转换为数组
  • 在模板中作为异步管道消耗
    this.metaData = backendPostReq(body)
      .pipe(
        mergeMap(item => item),   // splits the array into individual objects
        pluck('metaData', 'dataPie', 'data'), // plucks deeply nested property
        toArray()  // converted back to an array for ag grid
      )

    <ag-grid-angular
        *ngIf="metaData | async as result"
        [gridOptions]="dataCollectionConfig"
        [rowData]="result"
        [modules]="modules"
        class="ag-theme-balham data-collection-grid"
    >
    </ag-grid-angular>

RXJS 更好的方法来 map 和过滤器数组内部的 Observable<object><div id="text_translate"><p> 这是我想要完成的一个非常简单的版本。 目前它正在按预期工作,但我只是想知道是否有更短/更清洁的方法来实现 pipe() 内部的运算符</p><p><strong>当前行为:</strong>在包含数组“项目”的属性的可观察对象上调用 pipe。 在 pipe 内部,过滤、排序然后将项目发布到行为主体。</p><pre> public items$: BehaviorSubject public testObservable = () =&gt; of({ Test: '123', Properties: 'props', Items: [ { key: 1, val: 'test1' }, { key: 2, val: 'test2' }, { key: 3, val: 'test3' } ] }); testMethod() { this.testObservable().pipe( pluck('Items'), map(items =&gt; items.filter(item =&gt; item.key,= 2)). map(items =&gt; items,sort((a. b) =&gt; (a.key &gt; b?key: 1, -1))). tap(items =&gt; { this.items$;next(items) }) );</pre></div></object>

[英]RXJS better way to map and filter array inside of Observable<object>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM