Estoy tratando de implementar una llamada api que será
Traté de implementar lo que se menciona aquí: función Rxjs Retry with Delay
El siguiente es mi segmento de código
llamada API
delay = 5000; retryCount = 5; return this.httpClient.post(http://localhost:8080/info,JSON.stringify(data)) .pipe( retryWhen(errors => errors.pipe( delay(this.delay), take(this.retryCount), tap(val => { console.log('Retrying.'); }), concatMap(() => Observable.throw(new Error('Retry limit exceeded!'))) ) ) );Procesando la respuesta
this.searchService.searchInfo(param1, param2).subscribe(data => { this.handleSuccessResponse(data) }, (error) => { if (error) { // Handle specific error here handleErrorResponse(error); } }); handleSuccessResponse(data){ // handle success response here } handleErrorResponse(error){ // Handle generic error here }El problema que tengo, antes de volver a intentarlo 5 veces como mencioné en el código, es que se lanza la excepción en concatMap. ¿Qué me estoy perdiendo aquí?
Estoy usando RxJS 6.4 con Angular12
Revisé los documentos de learnRxjs y obtuve este método genérico, ¡que parece satisfacer sus requisitos!
import { Observable } from 'rxjs/Observable'; import { _throw } from 'rxjs/observable/throw'; import { timer } from 'rxjs/observable/timer'; import { mergeMap, finalize } from 'rxjs/operators'; export const genericRetryStrategy = ({ maxRetryAttempts = 3, scalingDuration = 1000, excludedStatusCodes = [], }: { maxRetryAttempts?: number; scalingDuration?: number; excludedStatusCodes?: number[]; } = {}) => (attempts: Observable<any>) => { return attempts.pipe( mergeMap((error, i) => { const retryAttempt = i + 1; // if maximum number of retries have been met // or response is a status code we don't wish to retry, throw error if ( retryAttempt > maxRetryAttempts || excludedStatusCodes.find((e) => e === error.status) ) { return _throw('Retry limit exceeded!'); } console.log( `Attempt ${retryAttempt}: retrying in ${ retryAttempt * scalingDuration }ms` ); // retry after 1s, 2s, etc... return timer(retryAttempt * scalingDuration); }), finalize(() => console.log('We are done!')) ); };Caso 1
res === null repeat siempre (retraso 500ms)Repita la llamada HTTP hasta que se devuelva el valor deseado con RxJs
retry 5 veces si hay un error de API (retraso de 500 ms) // RxJS 6.x api$.pipe( repeatWhen(delay(500)), skipWhile((res) => res === null), take(1), retryWhen(delayWhen((err, i) => i < 5 ? timer(500) : throwError(err))) ).subscribe(observer); // RxJS 7.x api$.pipe( repeat({ delay: 500 }), skipWhile((res) => res === null), take(1), retry({ count: 5, delay: 500 }) ).subscribe(observer);Caso 2
res === null + error de API = 5 veces (retraso de 500 ms) // RxJS 6.x api$.pipe( skipWhile((res) => res === null), throwIfEmpty(), retryWhen(delayWhen((err, i) => i < 5 ? timer(500) : throwError(err))) ).subscribe(observer); // RxJS 7.x api$.pipe( skipWhile((res) => res === null), throwIfEmpty(), retry({ count: 5, delay: 500 }) ).subscribe(observer);