【发布时间】:2021-05-04 23:25:00
【问题描述】:
我在奇怪的情况下使用以下方法通过为每个 HTTP 调用传递 pageIndex (1) 和 pageSize (500) 来检索数据。
this.demoService.geList(1, 500).subscribe(data => {
this.data = data.items;
});
响应有一个名为isMore 的属性,如果isMore 为真,我想更奇怪地修改我的方法以继续HTTP 调用。我还需要合并返回的值,最后返回累加的值。
例如,假设有 5000 条记录,并且直到第 10 次 HTTP 调用,服务会为 isMore 值返回 true。在第 10 次 HTTP 调用后,它返回 false,然后此方法将 this.data 值设置为合并的 5000 条记录。对于这个问题,我应该使用mergeMap 或expand 还是另一个RxJs 运算符?解决这个问题的正确方法是什么?
更新:我使用下面的方法,但是它没有合并返回值,也没有增加pageIndex。出于这个原因,它不起作用(我尝试进行一些更改,但无法使其起作用)。
let pageIndex = 0;
this.demoService.geList(pageIndex+1, 500).pipe(
expand((data) => {
if(data.isComplete) {
return of(EMPTY);
} else {
return this.demoService.geList(pageIndex+1, 500);
}
})
).subscribe((data) => {
//your logic here
});
更新二:
of({
isMore : true,
pageIndex: 0,
items: []
}).pipe(
expand(data => demoService.geList(data.pageIndex+1, 100)
.pipe(
map(newData => ({...newData, pageIndex: data.pageIndex+1}))
)),
// takeWhile(data => data.isMore), //when using this, it does not work if the total record is less than 100
takeWhile(data => (data.isMore || data.pageIndex === 1)), // when using this, it causing +1 extra HTTP call unnecessarily
map(data => data.items),
reduce((acc, items) => ([...acc, ...items]))
)
.subscribe(data => {
this.data = data;
});
更新三:
最后我通过修改 Elisseo 的方法使其工作,如下所示。但是,**我需要将其设为无效并在此 getData() 方法中设置 this.data 参数。我该怎么做?
getData(pageIndex, pageSize) {
return this.demoService.geList(pageIndex, pageSize).pipe(
switchMap((data: any) => {
if (data.isMore) {
return this.getData(pageIndex+1, pageSize).pipe(
map((res: any) => ({ items: [...data.items, ...res.items] }))
);
}
return of(data);
})
);
}
我想将以下订阅部分合并到这种方法,但由于某些错误,例如,我不能“'void' 类型上不存在属性 'pipe'。”
.subscribe((res: any) => {
this.data = res;
});
【问题讨论】:
-
我只需要在递归HTTP调用后累积返回值。我认为这是分页或递归需求的一般情况。有什么帮助吗?
-
我希望 RxJs 和 JavaScript 大师们看到这个问题并给出正确的解决方法:)
-
如果您使用分页,您不应该在事件发生后获取数据,例如 pageIndex 更改?如果您的方法是分页,为什么要尝试获取所有数据?如果您想获取每个数据,为什么要设置上限来获取数据?无法理解您尝试实现的逻辑。
-
谢谢朋友。其实这个方法是用来分页的,叫做点击下一个/上一个按钮,你是对的。但除此之外,我还需要通过检查响应的
isMore值来获取记录,因为随着将来记录的增加,给出一个固定的数字并不能解决问题。 -
在这个例子中不要考虑分页,只是认为我们需要使用从1开始的页码进行递归调用,然后检查响应的
isMore值。如果为真,继续递归调用,合并之前的结果。如果为 false,则只返回第一个响应中的记录。
标签: javascript reactjs angular typescript rxjs