TypeScriptのAngular2で記述されたWebアプリケーションの場合、RxJs Observable
sを使用する必要があります。
これまでrxjsを使用したことがなく、一般的にリアクティブプログラミングに慣れていないため、特定のことを行う正しい方法を見つけるのが難しい場合があります。
今、問題に直面しています。 _Array<Observable<T>>
_を_Observable<Array<T>>
_に変換する必要があります。
例を使用して説明します。
-Observable
があり、Users
(_Observable<Array<User>>
_)のリストが表示されます
-User
-クラスには、_Observable<Array<Post>>
_を返す関数getPosts
があります。
-_Observable<Array<User>>
_を_Observable<Array<Post>>
_にマッピングして、Post
関数内のすべてのonNext
sを評価する必要があります。
を使用して_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'.
_
だから私の質問は:Array
のObservables
をArray
に「フラット化」するにはどうすればよいですか?
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];
(...)
});
_
次のように、必要な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>
このオブザーバブルの配列でforkJoinを使用すると、オブザーバブルの配列になります。
[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))