我需要调用 api 并从端点获取所有项目。但是,我们一次只能获取 100 个项目。
响应如下所示:
{
elements: Array<any>,
totalCount: number,
}
Run Code Online (Sandbox Code Playgroud)
和端点将/api/items?drop=${drop}&take=100与drop被用来进行分页。
我认为这会涉及到 scan 和 takeWhile 操作符的某个地方..这是我得到的:
const subject = new Subject();
const rec = subject.pipe(
scan((acc: number, curr: number) => (curr + 100), 0),
switchMap(drop => this.http.get(`api/items?drop=${drop}&take=100`)),
takeWhile((r: any) => r.elements.length === 100),
tap(r => subject.next())
);
Run Code Online (Sandbox Code Playgroud)
您不需要知道将返回多少个元素,只需知道它永远不会返回多少个 :)
Observable.range(0, 1000000).pipe(
concatMap(page => this.http.get(`api/items?drop=${page * take}&take=${take}`))
takeWhile(results => results.elements.length === take)
)
Run Code Online (Sandbox Code Playgroud)
起初我认为使用rangeas source 会堆积请求并破坏分页的目的,但是 concatMap 提供了自动限制。
来自learnrxjs.io/operators/transformation/concatmap
注意 concatMap 和 mergeMap 之间的区别。因为 concatMap 在前一个完成之前不会订阅下一个 observable,所以将首先发出延迟 2000 毫秒的源值。将此与立即订阅内部 observable 的 mergeMap 进行对比,具有较小延迟(1000 毫秒)的 observable 将发出,然后是需要 2000 毫秒才能完成的 observable。
这是concatMap的一个测试,它显示getPage在之前的结果发出之前不会被调用
const take = 100;
const getPage = (page) => {
console.log('reading page', page);
return Rx.Observable.of(page).delay(1000);
}
Rx.Observable.range(0,3)
.concatMap(getPage)
.subscribe(results => console.log('concatMap results', results));Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.10/Rx.js"></script>Run Code Online (Sandbox Code Playgroud)
与mergeMap 相比,它使所有调用都getPage立即
const take = 100;
const getPage = (page) => {
console.log('reading page', page);
return Rx.Observable.of(page).delay(1000);
}
Rx.Observable.range(0,3)
.mergeMap(getPage)
.subscribe(results => console.log('mergeMap results', results));Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.10/Rx.js"></script>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2049 次 |
| 最近记录: |