Angular 2 RxJS可观察:重试当过滤器针对错误状态重试时 [英] Angular 2 RxJS Observable: RetryWhen filter retry on error Status

查看:86
本文介绍了Angular 2 RxJS可观察:重试当过滤器针对错误状态重试时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Angular 2 HTTP库,该库返回一个可观察值. 我想对某些错误状态/代码实施重试.

I am using Angular 2 HTTP library which returns an observable. I want to implement retry on certain error status/code.

我有一个问题,如果错误不是429,则在错误情况下将执行Observable.of(error)重试,但是当您所有的2次重试均失败时,流程的执行将转到成功块而不是catch块.

I have an issue, if the error is not 429, Observable.of(error) is getting executed in error case to retry, but when all your 2 retry fails the execution of flow goes to success block instead of catch block.

在所有重试中如何使流程执行以捕获块失败?

How to make execution of flow to catch block in all retry fails?

    return this.http.get(url,options)
           .retryWhen((errors) => {
                      return errors
                            .mergeMap((error) => (error.status === 429) ? Observable.throw(error) : Observable.of(error))
                            .take(2);
                     })
                       .toPromise()
                       .then((res:Response) => console.log('In Success Block'))
                       .catch((res) => this.handleError(res));

它将解决我的问题

        return this.http
  .post(url, JSON.stringify(body), requestOptions).retryWhen((errors) => {
    return errors
      .mergeMap((error) => (error.status === 404) ? Observable.throw(error) : Observable.of(error))
      .take(2);
  }).map((res:Response) =>{
    if (res.status === 200)
      return res;
    else
      return Observable.throw(res);
  })
  .toPromise();

推荐答案

聚会晚了一点,但是我最近实现了类似的行为.这是我的解决方案:

A little late to the party but, I recently implemented a similar behaviour. Here is my solution:

  post<T>(serviceUrl: string, data: any): Observable<T> {
    return Observable.defer(() => {
        return super.post<T>(serviceUrl, data);
    }).retryWhen((error) => {
        return this.refresh(error);
    });
}

和刷新功能:

refresh(obs: Observable<any>): Observable<any> {
    return obs
        .switchMap((x: any) => {
            if (x.status === 401) {
                return Observable.of(x);
            }
            return Observable.throw(x);
        })
        .scan((acc, value) => {
            return acc + 1;
        }, 0)
        .takeWhile(acc => acc < 3)
        .flatMap(() => {
            console.log('Token refresh retry');
            return this.tokenRefreshService.refreshToken();
        });
}

用例是,每当我发出HTTP请求并获得401响应时,我都希望刷新令牌,然后使用新令牌重试初始请求.当发生401时,我使用 switchMap 返回一个新的Observable,否则,我返回一个Observable.throw(x),它阻止了重试逻辑的执行.

The use case is that whenever I make an HTTP request and get a 401 response, I want to do a token refresh and then retry the initial request with the new token. When a 401 occurs I use switchMap to return a new Observable, otherwise, I return an Observable.throw(x) that stops the retry logic from being executed.

调用代码如下所示(每当您返回Observable.throw(x)时都会调用错误):

And the calling code looks like this (where error is called whenever you return an Observable.throw(x)):

 this.http.post(x).subscribe(response => {
      ...
        }
    }, error => {
        ...
        }
    });

这篇关于Angular 2 RxJS可观察:重试当过滤器针对错误状态重试时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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