簡體   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