2017-01-12 20 views
3

APIは複数のアイテムのリクエストをサポートしていないため、複数回行う必要があるAPI呼び出しがあります。私がこれまでに書いたことは、サーバーにGETリクエストを送信する無限ループに終わってしまいます。私は以下の例でObservablesの性質を理解していないと信じています。私の前提は、whileループの各呼び出しが新しい単一のオブジェクトにサブスクライブし、解決されると配列に配置されるということです。私が望むものを達成するために、以下のコードを変更するにはどうすればよいですか?複数の非同期HTTP GETリクエストを送信

getSingle(): Observable<Single> { 
    return this.http.get(this.url, this.options) 
    .map((r: Response) => r.json().data as Single); 
} 

getMultiple(num: number): Single[] { 
    let multiple: Single[] = []; 

    let i = 0; 
    while (i < num) { 
     this.getSingle().subscribe(single => { 
      multiple.push(single); 
      console.log('Success'); 
      i++; 
     }, err => { 
      console.log('Failure'); 
     }); 
    } 

    return multiple; 
} 

答えて

0

購読ブロックが何回も呼ばれ、その後RxJS対象と次の(使用することができますので、理想的にはあなただけそれはあなたの場合は、しかし、ループ内で)一度、コンストラクタで簡単な修正を

を購読うあまり気にしないでください:

this.getSingle().first().subscribe 

あなたは最初の演算子をインポートする必要があります。これにより、購読は一度だけ呼び出されます。あなたは何度も心配する必要はありません。

私はあなたが無限のHTTPリクエストを取得している理由を推測しているが、あなたの障害ブロックがヒットしていると、あなたがする必要があるということです...

}, err => { 
     i++; 
     console.log('Failure'); 
}); 
2

複数の非同期のHTTPリクエストを行うためにwhileループを使用して、それらのすべてを個別に購読することは、多くの接続が開かれないように避けるべきです。代わりにObservable.forkJoin演算子を使用できます。

getSingle(singleUrl: string): Observable<Single> { 
    return this.http.get(singleUrl, this.options) 
     .map((r: Response) => r.json().data as Single); 
}; 

getMultiple(): Observable<Array<Single>> { 
    let singleUrls = ['singleUrl1', 'singleUrl2', 'singleUrl3']; // can be replaced with any 'Single' identifier 

    let singleObservables = singleUrls.map((singleUrl: string, urlIndex: number) => { 
     return this.getSingle(singleUrl) 
      .map(single => single as Single) 
      .catch((error: any) => { 
       console.error('Error loading Single, singleUrl: ' + singleUrl, 'Error: ', error); 
       return Observable.of(null); // In case error occurs, we need to return Observable, so the stream can continue 
      }); 
    }); 

    return Observable.forkJoin(singleObservables); 
}; 

this.getMultiple().subscribe(
    (singles: Array<Single>) => { 
     console.log(singles); // [Single, Single, Single]; 
     // In case error occured e.g. for the 'singleUrl' (our 'Single' identifier) at position 1, 
     // Output wil be: [Single, null, Single]; 
    } 
); 

は、この情報がお役に立てば幸い:

これは、実装がのようになります方法です!

+0

「hackish」の「catch」で 'forkJoin'の代わりに' mergeDelayError'を使用することを検討してください:結果が配列に収縮されず、すべてのリクエストが完了したら適切な 'エラー'あなたが持っていた場合のコールバック。 – olivarra1

関連する問題