提问人:DeejC 提问时间:11/17/2023 更新时间:11/18/2023 访问量:23
如果仍在进行中,则不应重置 Rxjs 间隔请求,但如果用户更改输入,则应重置
Rxjs Interval request should not reset if still ongoing, but should reset if user changes input
问:
我有一个可观察对象,它结合了间隔和日期选择操作。我使用 and 对这两个可观察对象发出请求。这个想法是用户正在查看特定日期的表(可以随时更改),并且该表应每 20 秒更新一次(此时间可由用户配置)。combineLatest
switchMap
data$ = combineLatest(
this.refreshInterval$,
this.dateSelected$
).pipe(
switchMap(([_, date]) => this.requestDataForDate(date))
);
这有效,除非请求花费的时间超过 20 秒。如果请求耗时较长,则每次触发间隔时,它都会取消正在进行的请求并发出新的请求。这是有道理的,因为我使用的是 ,如果我更改为 ,那么这不会发生。switchMap
concatMap
但是,如果用户更改了日期,则应发出另一个请求,并取消前一个请求,这在使用 .concatMap
我怎样才能同时实现这两个目标?如果用户更改了日期,则无论如何都应重新提交请求,但如果在请求正在进行时触发了间隔,则不应重新提交请求
答:
0赞
MoxxiManagarm
11/18/2023
#1
我认为这在一个流 tbh 中是不可能的。
我能想到的最好的办法是创建 2 个流,然后将结果放入一个主题中。
data$ = dataSubject.asObservable();
this.refreshInterval$.pipe(
withLatestFrom(this.dateSelected$)
exhaustMap(([_, date]) => this.requestDataForDate(date)),
// some unsubscription
).subscribe(data => dataSubject.next(data));
this.dateSelected$.pipe(
switchMap(date => this.requestDataForDate(date)),
// some unsubscription
).subscribe(data => dataSubject.next(data));
2赞
akotech
11/18/2023
#2
作为基础,您可以:dateSelected$
首先到
switch
refreshInterval$
然后是请求的间隔
exhaust|concat
data$ = this.dateSelected$.pipe( switchMap((date) => this.refreshInterval$.pipe(exhaustMap(() => this.requestDataForDate(date))) ) );
评论
0赞
MoxxiManagarm
11/18/2023
我可能是错的,但这不会立即执行请求,只会在再次发出refreshInterval$时发出。在这种情况下,应创建一个新的可观察区间。好处:一旦日期更改,计时器也会再次启动
0赞
akotech
11/18/2023
@MoxxiManagarm你是完全正确的。但我假设他/她正在使用一个在订阅时立即发出的间隔(即)。否则,在他/她的原始示例中,还必须等待间隔触发第一个数据请求。timer(0,interval)
1赞
DeejC
11/20/2023
是的,你是对的,@akotech,我使用的是立即发射的计时器,所以你的解决方案效果很好。谢谢!
评论