可观察的重试/重试当使用flatmap时 [英] Observable retry / retryWhen with flatmap

查看:135
本文介绍了可观察的重试/重试当使用flatmap时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码来获取id,然后获取与id相关的数据。

I have the following code to get id and then data related to the id.

process(): Observable<any> {
    let id: number;
    return this.getId().flatMap(
        (response: number) => {
                id = response;
                return this.getData(id)
        }
    ).flatMap(
        (data: any) => {
            return Observable.of(data);
        }
    );
}

getData(id: number): Observable<any> {
    // retry if response.status is not complete
    return this.service.getData(id).map(response => return response.data); 
}

我想在getData方法上添加重试逻辑,直到response.status不是完成。我尝试在this.getData(id)之后添加重试/重试但没有运气。有什么建议吗?

I would like to add retry logic on getData method until response.status is not complete. I tried adding retry/retryWhen after this.getData(id) but no luck. Any suggestions please?

推荐答案

重试 retryWhen 适用于错误处理,这意味着源observable必须为这些运算符产生错误才能生效。我想在你的情况下,你想重试不是出错,而是你不喜欢的状态。

retry and retryWhen are suitable for error handling, meaning that the source observable has to produce an error for these operators to make an effect. I guess that in your case you want to retry not on error, but on a status that you don't like.

可能最简单的方法就是在某个时间间隔内拨打服务电话并按照您想要的状态进行第一次回复:

Probably the simplest way to achieve that would be to make service calls on some interval and take the first response with the status you want:

getData(id) {
    return Observable.interval(100)
        // make 5 attempts to get the data
        .take(5)
        .concatMap(() => this.service.getData(id))
        .filter(response => response.status === "complete")
        .take(1)
        .map(response => response.data)
}

现在 getData()返回一个observable要么发出一个对应于具有完整状态的响应的单个值,然后在完成5次尝试获取具有所需状态的数据失败后完成,或完成,而不会发出任何值(响应评论时更新了答案) )

Now getData() returns an observable that either emits a single value that corresponds to a response with a "complete" status and then completes, or completes without emitting any value after 5 unsuccessful attempts to get the data with the desired status (the answer updated in response to a comment).

U pdate:

当然,可以将错误状态的响应转换为错误并使用重试功能,正如您所建议的那样:

It is, of course, possible to turn responses with "bad" statuses into errors and use the retry functionality, as you proposed:

getData(id) {
    return this.service.getData(id)
        .concatMap(response => response.status === "complete" ?
            Observable.of(response) :
            Observable.throw("Bad status"))
        .map(response => response.data)
        .retry(5);
}

如果出现问题,此代码将尝试获取最多6个数据时间(1个初始值+ 5个重试次数)然后将产生一个您必须处理的错误,例如使用 catch 运算符。一个缺点是这种方式不能将真实错误(例如网络故障)与错误状态产生的错误区分开来,但这可以通过 retryWhen 来处理。

If things go wrong, this code will try to fetch the data at most 6 times (1 initial + 5 retries) and then will produce an error that you would have to handle, for example with catch operator. One drawback is that this way does not distinguish "real" errors (e.g. network failures) from errors produced out of bad statuses, but this could be handled with retryWhen.

这篇关于可观察的重试/重试当使用flatmap时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆