我写了一个函数在一个API上做轮询,这个API也可以做分页。在这里,分页是使用Subject Observable完成的,轮询是使用timer方法完成的(我也尝试了interval,结果相同)。
下面是我的代码:
getItems(pagination: Subject<Pagination>): Observable<ListResult<Item>> {
let params: URLSearchParams = new URLSearchParams();
return Observable
.timer(0, 5000)
.combineLatest(
pagination,
(timer, pagination) => pagination
)
.startWith({offset: 0, limit: 3})
.switchMap(pagination => {
params.set('skip', pagination.offset.toString());
params.set('limit', pagination.limit.toString());
return this.authHttp.get(`${environment.apiBase}/items`, {search: params})
})
.map(response => response.json() as ListResult<Item>)
.catch(this.handleError);
}
预期行为为:HTTP请求每5秒触发一次,并且在用户更改页面时触发。
这是发生了什么:第一个HTTP请求被激发,但是在使用分页之前,没有其他请求被发送到服务器。第一次使用分页后,轮询也开始工作。
这是我第一次使用Observables,所以我很确定我错过了一些东西,但我看不到它可能是什么。
我也尝试过这种方法(可能是startWith中缺少了计时器计数器),但它没有改变任何东西。
[...]
.combineLatest(
pagination
)
.startWith([0, {offset: 0, limit: 3}])
[...]
2条答案
按热度按时间5vf7fwbs1#
combineLatest()
操作符要求所有源Observables至少发出一个项目。您的演示只发出一个请求,因为您使用的是
.startWith()
。combineLatest()
永远不会发出,因为pagination
是Subject
,它可能永远不会发出任何项。因此,一个选项是移动
.startWith()
:但这可能对您没有多大帮助,因为您忽略了来自
timer()
的所有项,而您只使用了pagination
。因此,您可以只使用merge()
来刷新其中一个源的列表。然后timer()
独立地增加偏移。0md85ypi2#
确保您遵循以下步骤
创建可观测数据
您有一个Observable变量,并且按
observable.next(value);
推送数据将数据放入Subject或Behavior Subject
在想要获取数据的地方,您声明了一个Subject类型变量,并通过订阅它来访问它。
现在您可以在任何地方使用uiVal,它将在每个interval中更新。
您可以通过制作
console.log
来分别测试这两个部件,以确保一切正常。