私のアプリには次のようなものがあります:
this._personService.getName(id)
.concat(this._documentService.getDocument())
.subscribe((response) => {
console.log(response)
this.showForm()
});
//Output:
// [getnameResult]
// [getDocumentResult]
// I want:
// [getnameResult][getDocumentResult]
次に、2つの個別の結果を取得します。最初は_personService
、次に_documentService
です。 this.showForm()
を呼び出して終了し、それぞれの結果を操作する前に、両方の結果を待つにはどうすればよいですか。
以前にZip
メソッドの使用を提案しました。しかし、それ以来、代わりにcombineLatest
を使用していることに気付きました。そこで、combineLatest
を追加することにしました。
CombineLatest
は、オブザーバブルから最新の発行値を発行します。 Zip
メソッドは、放出された項目をsequence順序で放出します。
たとえば、オブザーバブル#1がrdアイテムを放出し、オブザーバブル#2が5thアイテムを放出した場合。 Zip
メソッドを使用した結果は、両方のobservables
の-rd発行値になります。
この場合、combineLatest
を使用した結果は5thおよびrdになります。より自然に感じます。
ReactiveXから ドキュメント :
入力Observableが値を出力するたびに、すべての入力から最新の値を使用して式を計算し、その式の出力を出力します。
// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
combineLatest(name$, document$, (name, document) => ({name, document}))
.subscribe(pair => {
this.name = pair.name;
this.document = pair.document;
this.showForm();
})
Observable.Zipメソッドは reactiveX documentation で説明されています:
複数のObservableを組み合わせて、各入力Observableの値から順番に値が計算されるObservableを作成します。
// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
Observable
.Zip(name$, document$, (name: string, document: string) => ({name, document}))
.subscribe(pair => {
this.name = pair.name;
this.document = pair.document;
this.showForm();
})
関数を提供した最後のパラメーター(name: string, document: string) => ({name, document})
はオプションです。スキップするか、より複雑な操作を行うことができます。
最新のパラメーターが関数の場合、この関数は入力値から作成された値を計算するために使用されます。それ以外の場合、入力値の配列が返されます。
したがって、最後の部分をスキップすると、配列が取得されます。
// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
Observable
.Zip(name$, document$)
.subscribe(pair => {
this.name = pair['0'];
this.document = pair['1'];
this.showForm();
})
オブザーバブルのforkJoin()
メソッドを使用します。 参照用にこのリンクを確認してください
RXJSから docs
この演算子は、オブザーバブルのグループがあり、それぞれの最終的な放出値のみを考慮する場合に最適です。これの一般的な使用例は、ページの読み込み(または他のイベント)で複数のリクエストを発行し、すべてのレスポンスが受信されたときにのみアクションを実行する場合です。この方法では、 Promise.all を使用する方法に似ています
Observable.forkJoin([character, characterHomeworld]).subscribe(results => {
// results[0] is our character
// results[1] is our character homeworld
results[0].homeworld = results[1];
this.loadedCharacter = results[0];
});
から取得したコード: https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs
ダミーのRxJS演算子:forkJoin、Zip、combineLatest、withLatestFrom が非常に役立ちました。名前が示すように、次の組み合わせ演算子を説明します。
それらのいずれかは、場合に応じて、あなたが探しているものになる可能性があります。詳細については、記事を確認してください。
私にとってこれは sample が最良の解決策でした。
const source = Observable.interval(500);
const example = source.sample(Observable.interval(2000));
const subscribe = example.subscribe(val => console.log('sample', val));
だから.. 2番目(例)が放出するときのみ-最初(ソース)の最後に放出された値が表示されます。
私のタスクでは、フォームの検証と他のDOMイベントを待ちます。
「combineLatest」メソッドを見てください。ここで適切かもしれません。 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-combineLatest
const { Observable } = Rx
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
Observable
.combineLatest(name$, document$, (name, document) => ({ name, document }))
.first() // or not, implementation detail
.subscribe(({ name, document }) => {
// here we have both name and document
this.showForm()
})
次のように「Zip」または「buffer」を使用できます。
function getName() {
return Observable.of('some name').delay(100);
}
function getDocument() {
return Observable.of('some document').delay(200);
}
// CASE1 : concurrent requests
Observable.Zip(getName(), getDocument(), (name, document) => {
return `${name}-${document}`;
})
.subscribe(value => console.log(`concurrent: ${value}`));
// CASE2 : sequential requests
getName().concat(getDocument())
.bufferCount(2)
.map(values => `${values[0]}-${values[1]}`)
.subscribe(value => console.log(`sequential: ${value}`));