網站搜尋

angular - 發送多個非同步 HTTP GET 請求


我有一個 API 呼叫,需要多次呼叫,因為 API 不支援多個項目的請求。我目前寫的內容最終會陷入無止盡的循環,不斷向伺服器發送 GET 請求。我認為我不太理解以下範例中可觀察量的本質。我假設 while 迴圈中的每個呼叫都會訂閱一個新的單一物件,當它被解析後,它會被放進陣列中。我該如何修改以下程式碼以達成我想要的效果?

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;
}

答案#1

使用 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];
    }
);

希望這對你有幫助!

答案#2

理想情況下,你應該只在建構函數中訂閱一次,因為訂閱區塊可能會被調用多次,然後在迴圈內使用 RxJS subject 並調用 next()

然而,如果你不是很在意,一個快速的解決辦法是:

this.getSingle().first().subscribe

你需要導入第一個運算子。這將確保 subscribe 只被調用一次。這樣你就可以多次訂閱,無需擔心。

我猜您之所以收到無限的 HTTP 請求,是因為您的失敗區塊被觸發,您需要進行...

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