2017-01-12 201 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主題和next()其內循環

然而,速戰速決,如果你不要太在意:

this.getSingle().first().subscribe 

您將需要導入第一個運算符。這將確保僅訂閱僅被調用一次。這樣你可以分多次不用擔心。

我猜你得到無限的HTTP請求的理由是,你失敗塊被擊中,你需要做的......

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

使用while循環,使多個異步HTTP請求,然後再單獨訂閱它們以避免打開多個Observable連接。我們可以使用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

考慮使用'mergeDelayError'而不是'forkJoin'和'hackish''catch':它的好處是它不會將結果壓縮到一個數組中,並且當所有的請求都完成時,你將得到一個正確的'error '如果你有任何回撥的話。 – olivarra1