API 轮询和超时
Posted
技术标签:
【中文标题】API 轮询和超时【英文标题】:API polling and timeout 【发布时间】:2018-08-17 11:16:25 【问题描述】:我有一个轮询用例:
-
我想调用一个基于业务逻辑的 API,它会立即(1.5-2 秒)返回数字 (1-10) 或错误(API 中的网络问题/异常等)。
如果 API 返回错误(网络问题/API 中的异常等),那么我想取消订阅轮询并显示错误。
如果 API 返回成功,我想检查返回值并取消订阅(如果返回值为 5)或继续轮询。
我想每 5 秒调用一次 API。
我想将轮询的最长时间(超时/阈值)保持为 3 分钟。如果我在这 3 分钟内没有得到所需的响应(数字 5),则轮询应该会出错。
这是我目前的实现方式:
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
但是,上面的实现并没有超时。
需要做什么才能超时并且我能够实现所有提到的用例?
【问题讨论】:
interval(5000)
每 5 秒发出一次,因此之后的超时将永远不会引发错误,因为它每 5 秒接收一个值
知道了。现在我该如何超时?
每当我看到 polling 和 API ...我不得不问,你考虑过使用消息队列吗?
【参考方案1】:
首先使用interval
进行API 轮询是一种反模式,因为interval
不会“等待”您的http 请求完成——可能会触发多个请求(如果请求需要5 秒以上才能完成) )。
我更喜欢将defer
与repeatWhen
和delay
一起使用(参见下面的代码)。
timeout
未触发,因为interval
每 5 秒滴答一次,防止超时发生。 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";
【讨论】:
以上是关于API 轮询和超时的主要内容,如果未能解决你的问题,请参考以下文章