我创建了一个可观察的计时器来调用这样的HTTP调用,
this.timer = Observable
.timer(0, 30000)
.switchMap(() => this.getMyData())
.share();
getMyData(){
return this.http.get(this.url, this.options )
.map(this.extractDataFromAPI)
.retry(3)
.catch(this.handleError)
.share();
这适用于每30秒调用一次api,但是在我对数据进行编辑后,我希望立即刷新数据,而不是等待计时器超时,但我不知道这样做的正确方式。
有人知道是怎么回事吗?我试着取消订阅和重新订阅,但似乎不起作用。有没有更好的方法来做这件事?
另外,两个.share()都需要吗?
发布于 2018-05-10 22:52:58
每30秒重新加载一次可能不是一个好主意,你应该在这种情况下使用websocket,但为了回答你的问题,你可以这样做:
class A {
private forceReload = new Subject<void>();
private timer = Observable.timer(0, 30000)
.combineLatest(this.forceReload)
.switchMap(() => this.getMyData())
.share();
getMyData() {
return this.http
.get(this.url, this.options)
.map(this.extractDataFromAPI)
.retry(3)
.catch(this.handleError)
.share();
}
reloadData() {
this.forceReload.next();
}
}
当您想强制重新加载数据时,只需注入您的服务(此处为A
)并执行以下操作:
myAServiceInstance.reloadData();
发布于 2018-05-10 22:47:20
尝试单独使用interval
,每隔30秒触发一次observable
setInterval (()=> {
his.httpRequest();
}, 30000);
httpRequest(){
..Observable..subscribe(res =>{
this.variableToUpdate = res;
});
}
发布于 2018-08-19 02:07:31
我使用了另一种方法来解决这个问题。
private refresh$ = new Subject<void>();
get items(): Observable<T[]> {
return this.getItems();
}
refresh(): void {
this.refresh$.next();
}
getItems(): void {
const timer$ = timer(0, 30000);
const items$ = this.refresh$.pipe(
startWith(null),
switchMap(_ => timer$),
switchMap(_ => this.getItems()),
shareReplay()
);
return items$;
}
尽管我不是rxjs方面的专家,但我认为它是如何工作的:
在第一次订阅时,将立即发出空值。定时器将被订阅,并每30秒发出一次值,这将触发一个http请求。
这将继续,直到调用刷新,此时将发出一个新值(未定义)。定时器在switchMap中的原因是为了确保每次刷新可观测对象发出时都取消(取消订阅)定时器。每次发生这种情况时,都会重新订阅计时器。
最后,shareReplay的作用是确保所有订阅者都收到相同的数据副本。
我没有特别的理由在发出请求时使用switchMap,除了它是rxjs中最安全的映射操作符之外(文档上是这么说的)。
希望这是有用的。
https://stackoverflow.com/questions/50274959
复制相似问题