2017-02-06 12 views
1

複数のコールが作成されており、別のページにルーティングする前にすべてのコールが完了するのを待つ必要があります。私が実行している問題は、典型的にはWebサービス呼び出しを入れ子にしているということですが、この場合、ユーザーの入力に基づいて呼び出されるかどうかは別々の呼び出しがあります。新しいページにルーティングする前に呼び出される場合と呼び出されない場合があるすべての呼び出しを待つ方法観察が完了するのを待つ方法は?角2

submitButton_Clicked() { 
    this.busy = this.service.call1() // must be called 
    .first().subscribe(
     if (success){ 

     // **Logic to decide if call 2 is needed** 
     ... 

     this.busy = this.service.call2() // might be called 
      .first().subscribe(); 

     // **Logic to decide if call 3 is needed** 
     ... 

     this.busy = this.service.call3() // might be called 
      .first().subscribe(); 

     this.router('route'); // should route after all potential calls 
     } 
    ); 
} 

私はobservablesには新しいので、これを実行する最良の方法は何か分かりません。助けてくれてありがとう!

+0

あなたが約束を使用していた場合、あなたはこれを達成するためにpromise.allを使用することができます。しかし、私はそれがあなたの後の答えではないことがわかります。 – n00b

+0

それぞれを条件付きで購読するのではなく、それぞれを条件付きで自分自身または空の観測可能なものにマッピングし、これらの可能性のある空のストリームをすべて新しいストリームにマージまたは連結し、reduceおよびsubscribeを呼び出します。 –

+1

http://stackoverflow.com/documentation/rxjs/8247/common-recipes/28035/sending-multiple-sequential-http-requests#t=201702081844368442112またはhttp://stackoverflow.com/documentation/rxjs/8247を参照してください。 /共通レシピ/ 27973 /送信複数並列httpリクエスト#t = 2017020818445186661 – martin

答えて

1

あなたはflatMap

let Observable = Rx.Observable; 

let f = Observable.of(20).delay(1000); 
let g = f.map(x => x*x) 
    .flatMap(x => Observable.of(x + 100)); 

g.subscribe(console.log); 


/** 
* Rx.Observable.prototype.flatMap 
* and Rx.Observable.prototype.selectMany 
* are equivalent. 
*/ 

let h = f.map(x => x*3) 
    .delay(1000) 
    .flatMap(x => Observable.of(x + 100)); 
h.subscribe(console.log); 

https://jsbin.com/vokofug/edit?js,console,output

または連結またはマージ使用できます

CONCAT()ストリームは、最初のソース1からすべての値を印刷し のみ開始されますがsource1の完了後にsource2から値を出力します。

が受け取るように、merge()ストリームはsource1とsource2の値を出力します。 が第2ストリームから値を出力する前に、最初のストリームが完了するまで待機しません。

http://codepen.io/SitePoint/pen/PzKdVQ

'use strict'; 

const source1 = 
    Rx.Observable.interval(100) 
    .map(val => `Source 1: ${val}`) 
    .take(5); 

const source2 = 
    Rx.Observable.interval(100) 
    .map(val => `Source 2: ${val * 10}`) 
    .take(5); 

const concat_table = $('#concat-table-body'), 
     merge_table = $('#merge-table-body'); 

source1 
    .concat(source2) 
    .subscribe(value => { 
    const row = document.createElement('tr'); 
    row.innerHTML = value; 

    // Source 1 values populate BEFORE Source 2 
    concat_table.append(row); 
    }); 

source1 
    .merge(source2) 
    .subscribe(value => { 
    const row = document.createElement('tr'); 
    row.innerHTML = value; 

    // Source 1 values INTERLEAVE with Source 2 
    merge_table.append(row); 
    }); 
関連する問題