javascript - RXJS 分頁的 while 迴圈
我嘗試從 swap api 查詢所有人的資料。URL swapi.co/api/people 返回一個包含 people 陣列的物件,而在 URL(swapi.co/api/people/?page=2) 我可以獲取下一頁的資料。我想做的是,每當有新的一頁資料可用時,subscribe 方法就會更新 angular 元件。
我對反應式編程模型還很陌生。我該如何實現 while 迴圈或一系列的 Observables?
這適用於第一頁:
getAllPeople(): Observable<Person[]> {
let nextUrl = http://swapi.co/api;
let source = Observable.create(observer => {
this.http.get(nextUrl, { headers: this.headers })
.map(response => {
let body = response.json();
nextUrl = body.next;
return nextUrl != null ? body.results as Person[] : null;
}
)
.retry(5)//send same request based on the url of the previous request till the field next is null
.catch(error => observer.error(error))
.subscribe(persons => {
if (persons !== null) {
observer.next(persons)
}
}
);
//observer.complete();
})
return source;
}
編輯:我添加了 retry() 方法。我希望這樣更容易理解我的意圖。第一次請求後,它會向相同的 URL 發送更多請求。不幸的是,它沒有使用我從先前請求中獲得的新 URL。
http://swapi.co/api/?page=1 -> http://swapi.co/api/?page=2 -> http://swapi.co/api/?page=3 -> 無
我不知道我需要多少次請求才能檢索所有數據。
答案#1
透過使用 expand 運算子,你可以為每個返回的值創建一個新的 Observable 序列。要停止 expand 創建任何新的序列,一旦我們得到下一個為 null 的 URL,我們可以返回一個空的 Observable 來停止擴展我們的序列。最後,我們可以使用 reduce 運算子將不同頁面的資料聚合成一個陣列,然後再發出回原始的訂閱者。這可以透過以下方式實現:
public getAllPeople(): Observable<Person[]> {
return Observable.create(observer => {
this.getPage("http://swapi.co/api/people/")
.expand((data, i) => {
return data.next ? this.getPage(data.next) : Observable.empty();
})
.reduce((acc, data) => {
return acc.concat(data.results);
}, [])
.catch(error => observer.error(error))
.subscribe((people) => {
observer.next(people);
observer.complete();
});
});
}
private getPage(url: string): Observable<{next: string, results: Person[]}> {
return this.http.get(url, { headers: this.headers })
.map(response => {
let body = response.json();
return {
next: body.next,
results: body.results as Person[]
};
}
);
}
