web-dev-qa-db-ja.com

RxJs配列のObservableの配列

TypeScriptのAngular2で記述されたWebアプリケーションの場合、RxJs Observablesを使用する必要があります。
これまでrxjsを使用したことがなく、一般的にリアクティブプログラミングに慣れていないため、特定のことを行う正しい方法を見つけるのが難しい場合があります。
今、問題に直面しています。 _Array<Observable<T>>_を_Observable<Array<T>>_に変換する必要があります。
例を使用して説明します。
-Observableがあり、Users(_Observable<Array<User>>_)のリストが表示されます
-User-クラスには、_Observable<Array<Post>>_を返す関数getPostsがあります。
-_Observable<Array<User>>_を_Observable<Array<Post>>_にマッピングして、Post関数内のすべてのonNextsを評価する必要があります。

を使用して_Observable<Array<User>>_から_Observable<Array<Observable<Array<Post>>>>_に簡単にマッピングできます
map((result : Array<User>) => result.map((user : User) => user.getPosts()))
ans _Array<Array<Post>>_を_Array<Post>_にフラット化できます。
ただし、_Observable<Array<Observable<Array<Post>>>>_を_Observable<Array<Array<Post>>>_にマップする正しい方法が見つかりません
今までは、combineLatestと一緒にflatMap関数を使用していました。
私には動作しているようで、使用したエディター(Atomエディター)にはエラーは表示されませんでした。ただし、今はNetbeansを使用しています。このコードでエラーが表示されます。また、「tsc」を使用してコードをコンパイルすると、エラーが発生します。
このような外観:

_Argument of type '(result: Post[]) => void' is not assignable to parameter of type 'NextObserver<[Observable<Post>]> | ErrorObserver<[Observable<Post>]> | CompletionObserver<[...'.
Type '(result: Post[]) => void' is not assignable to type '(value: [Observable<Post>]) => void'.  
_

だから私の質問は:
ArrayObservablesArrayに「フラット化」するにはどうすればよいですか?

22
Springrbua

flatMap演算子はそれを可能にします。私はあなたが何をしようとしているのか完全には理解していませんが、答えを提供しようとします...

すべてをロードする場合

_getPostsPerUser() {
  return this.http.get('/users')
    .map(res => res.json())
    .flatMap((result : Array<User>) => {
      return Observable.forkJoin(
        result.map((user : User) => user.getPosts());
    });
}
_

_Observable.forkJoin_を使用すると、すべてのオブザーバブルがデータを受信するのを待つことができます。

上記のコードは、user.getPosts()がobservableを返すと仮定しています...

これにより、投稿の配列の配列を受け取ります:

_this.getPostsPerUser().subscribe(result => {
  var postsUser1 = result[0];
  var postsUser2 = result[1];
  (...)
});
_
31

次のように、必要なrxjsメソッドで関数applyを使用できます。

const source1 = Rx.Observable.interval(100)
  .map(function (i) { return 'First: ' + i; });

const source2 = Rx.Observable.interval(150)
  .map(function (i) { return 'Second: ' + i; });

const observablesArray = [source1, source2];

const sources = Rx.Observable.combineLatest
.apply(this, observablesArray).take(4)

/* or you can write it without "apply" this way:
const sources = Rx.Observable
                .combineLatest(...observablesArray)
                .take(4)
*/
sources.subscribe(
  (response) => {
    console.log(response);
  }
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.min.js"></script>
8
Julian FARHI

このオブザーバブルの配列でforkJoinを使用すると、オブザーバブルの配列になります。

2
r ne

[email protected]を使用したコードの例を次に示します

import { of, forkJoin} from 'rxjs';
import { Observable } from 'rxjs'

const source:Array<Observable<String>> = [of('A'), of('B'), of('C') ];

forkJoin(source).subscribe( (x)=> console.log(x))

https://arrayofobservablesexamp.stackblitz.io

2