我有一个轮询用例,其中:
这是我目前实施的方式:
this.trackSpoke$ = interval(5000)
.pipe(
timeout(250000),
startWith(0),
switchMap(() =>
this.sharedService.pollForAPropertyValue(
"newuser"
)
)
)
.subscribe(
(data: SpokeProperty) => {
this.CheckSpokeStatus(data);
},
error => {
this.trackSpoke$.unsubscribe();
this.createSpokeState.CdhResponseTimedOut();
}
);
private CheckSpokeStatus(data) {
if (data.PropertyValue === "5") {
this.trackSpoke$.unsubscribe();
//display success
} else {
//keep the polling going
}
}
但是,以上实现并未超时。
需要做些什么才能使它超时并能够实现所有提到的用例?
答案 0 :(得分:1)
首先使用interval
进行API轮询是一种反模式,因为interval
不会“等待”您的http请求完成-可能触发多个请求(如果请求需要更多请求然后5s完成)。
我更喜欢将defer
与repeatWhen
和delay
结合使用(请参见下面的代码)。
timeout
不会触发,因为interval
每5s滴答一次,以防止发生超时。 defer
/ repeatWhen
组合也应该解决此问题。
请考虑使用takeWhile
为您取消订阅Observable,而不是手动取消订阅。
也不需要在错误处理程序中使用this.trackSpoke$.unsubscribe();
,因为在发生错误时会自动取消预订Observable。
this.trackSpoke$ = defer(() => this.sharedService.pollForAPropertyValue("newuser"))
.pipe(
timeout(250000),
repeatWhen(notifications => notifications.delay(5000)),
takeWhile(data => this.CheckSpokeStatus(data)),
)
.subscribe(
error => {
this.createSpokeState.CdhResponseTimedOut();
}
);
private CheckSpokeStatus(data) {
return data.PropertyValue !== "5";
}