2017-02-27 10 views
8

私のバックエンドは、RxJS 5 Observable(角2を使用しています)内に配列としてデータを返すことがよくあります。RxJS Observable内で配列を「平坦化する」最良の方法

私はしばしば自分が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によって放出された配列のメンバーに変換を適用するより良い方法はありますか?

NB。私は、RxJS演算子(vs配列メソッド)が私のアイテムを変換することを望んでいます。なぜなら、各アイテムを第2の観測可能物に投影する能力が必要だからです。典型的な使用例:アイテムIDのリストのバックエンド戻り値と、これらのアイテムのすべてをバックエンドから要求する必要があります。

答えて

6

パラメータなしでconcatAll()またはmergeAll()を使用できます。この(mergeMap含む)

dataFromBackend 
    .do(items => console.log(items)) 
    .mergeAll() // or .concatAll() 

は、それが扱うため観測、アレイ、アレイ状物、約束など同様のみRxJS 5に働きます。

結局あなたも行うことができます:実際に

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(); 
+0

ありがとう、マーティン。 'concatAll()'が元の配列内の項目の順序を保持し、 'mergeAll()'は保持しないというのは正しいですか? – AngularChef

+2

@AngularFranceあなたは配列をアンパックしているので、どちらを使うかは関係ありませんし、どちらも注文アイテムを生成します。これは、この場合ではない非同期操作で使用する場合にのみ関係します。 – martin

1

を、それは同期動作であれば、私はジャバスクリプトのArray.map代わりを使用することをお勧めします、それもあなたにいくつかのパフォーマンスを保存する必要がありますあなたはストリームの中でそれを必要とします:

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

それは事であり、私は自分自身がそれぞれのアイテムを第2の観察可能なものに投影していることが多い。典型的な使用例:アイテムIDのリストのバックエンドの戻り値と、これらのアイテムのすべてをバックエンドから要求する必要があります。私はそれを私の質問に含めるべきだった。 – AngularChef

+0

これはあなたのストリームを構築する方法に関して違いを生みますが、その場合はおそらく@ martinの答えが良いでしょう。私はここで個人的な(わずかに関係のない)コメントを作らなければならない:それは一般的に悪いRESTアーキテクチャ最初にIDのリストを要求してから、単一の休憩コールで詳細を個別に取得します。これはサーバーの悩みであり、最初の1回の呼び出しですべてのデータを取得するよりも時間がかかります。 – olsn

+0

しかし、時にはわかっているように、我々はAPIの単なる消費者*であり、*クリエイター*ではありません。ちょうど最近、Gmail JavaScript APIを使用して説明したユースケースに直面しました(キーのリストを個別に呼び出し、次にエンティティ自体を呼び出す必要があります)。 – AngularChef

0

場合:

.mergeMap(val => Observable.from(val) 
    .do(item => console.log(item)) 
    .map(item => item.name) 
) 
.toArray() 
関連する問題