2016-10-08 3 views
3

Я использую библиотеку HTTP Angular 2, которая возвращает наблюдаемую. Я хочу реализовать повторную попытку с определенным статусом/кодом ошибки.Угловой 2 RxJS Наблюдаемый: Повторить попытку фильтра после ошибки Состояние

У меня проблема, если ошибка не 429, Observable.of(error) получает выполнение в случае ошибки, чтобы повторить попытку, но когда все ваши повторные попытки не выполняются, выполнение потока переходит к блоку успеха вместо блока catch.

Как сделать выполнение потока для захвата блока во всех попытках неудачи?

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(); 
+1

http://stackoverflow.com/questions/39480348/angular-2- rxjs-observable-retry-except-on-429-status/39928110 # 39928110 –

ответ

7

Немного опоздал на вечеринку, но я недавно реализовал подобное поведение. Вот мое решение:

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.throw (x), который останавливает выполнение логики повтора.

И вызывающий код выглядит следующим образом (где называется ошибка, когда вы возвращаете Observable.throw (х)):

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

Я пробовал ваш код, он работал хорошо. Огромное спасибо. –

Смежные вопросы