【问题标题】:API polling and timeoutAPI 轮询和超时
【发布时间】:2018-08-17 11:16:25
【问题描述】:

我有一个轮询用例:

  1. 我想调用一个基于业务逻辑的 API,它会立即(1.5-2 秒)返回数字 (1-10) 或错误(API 中的网络问题/异常等)。
  2. 如果 API 返回错误(网络问题/API 中的异常等),那么我想取消订阅轮询并显示错误。
  3. 如果 API 返回成功,我想检查返回值并取消订阅(如果返回值为 5)或继续轮询。
  4. 我想每 5 秒调用一次 API。
  5. 我想将轮询的最长时间(超时/阈值)保持为 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 ...我不得不问,你考虑过使用消息队列吗?

标签: angular rxjs observable reactive-programming polling


【解决方案1】:

首先使用interval 进行API 轮询是一种反模式,因为interval 不会“等待”您的http 请求完成——可能会触发多个请求(如果请求需要5 秒以上才能完成) )。

我更喜欢将deferrepeatWhendelay 一起使用(参见下面的代码)。

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";
}

【讨论】:

    猜你喜欢
    • 2020-02-22
    • 2012-02-22
    • 1970-01-01
    • 2012-10-12
    • 2021-10-13
    • 1970-01-01
    • 2022-01-11
    • 2011-02-06
    • 1970-01-01
    相关资源
    最近更新 更多