Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

330
Views
Cómo repetir una promesa condicionalmente usando rxjs

Me gustaría repetir una llamada API que devuelve una Promesa, condicionalmente usando rxjs.

El método API recibe una identificación que se cambiará en cada llamada al agregarle un prefijo de contador. Las llamadas se repetirán hasta que los datos cumplan alguna condición o el contador llegue a un número específico X. ¿Cómo se puede hacer usando rxjs?

Método API:

fetchData(id):Promise<data>

prueba 1: fetchData (id)

prueba 2: buscar datos (id_1)

prueba 3: buscar datos (id_2)

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

En mi opinión, es mejor manejar el sondeo a través de Promises o RxJS sin mezclarlos. Ilustraría usando RxJS.

Prueba lo siguiente

  1. Convierta la promesa en un observable usando la función from RxJS.
  2. Use funciones RxJS como timer o interval para emitir regularmente un valor en un intervalo fijo.
  3. Use un operador de mapeo de orden superior como switchMap para mapear desde la emisión externa a su llamada API. Consulte aquí para obtener una breve descripción sobre los diferentes tipos de operadores de mapeo de orden superior.
  4. Utilice dos operadores takeWhile , uno para cada una de sus condiciones respectivamente, para completar la suscripción.
  5. Use el operador de filter para enviar solo las emisiones que pasan la condición.
 import { from } from 'rxjs'; fetchData(id: any): Observable<any> { // <-- return an observable return from(apiCall); // <-- use `from` to convert Promise to Observable }
 import { timer } from 'rxjs'; import { filter, switchMap, takeWhile } from 'rxjs/operators'; timer(0, 5000).pipe( // <-- poll every 5 seconds takeWhile((index: number) => index < 20) // <-- stop polling after 20 attempts switchMap((index: number) => this.someService.apiCall(index+1) // <-- first emission from `timer` is 0 ), takeWhile( // <-- stop polling when a condition from the response is unmet (response: any) => response.someValue !== someOtherValue, true // <-- emit the response that failed the test ), filter((response: any) => response.someValue === someOtherValue // <-- forward only emissions that pass the condition ) ).subscribe({ next: (response: any) => { // handle response }, error: (error: any) => { // handle error } });

Editar: la condición en el takeWhile estaba haciendo lo contrario del requisito. Ajusté la condición e incluí el argumento inclusive=true . Gracias @Siddhant en los comentarios.

about 4 years ago · Juan Pablo Isaza Report

0

Puede usar concatMap para asegurarse de que solo se intente una llamada a la vez. range proporciona el número máximo de llamadas porque takeWhile cancelará la suscripción anticipadamente (antes de que finalice el rango) si se cumple/no se cumple una condición.

Eso podría verse así:

 // the data met some condition function metCondition(data){ if(data/*something*/){ return true; } else { return false } } // the counter reach to a specific number X const x = 30; range(0, x).pipe( concatMap(v => fetchData(`id_${v === 0 ? '' : v}`)), takeWhile(v => !metCondition(v)) ).subscribe(datum => { /* Do something with your data? */ });
about 4 years ago · Juan Pablo Isaza Report

0

Podría intentar reintentar cuando:

 let counter=0; const example = of(1).pipe( switchMap(x => of(counter)), // Replace of() with from(fetchData('id_'+counter)) map(val => { if (val < 5) { counter++; // error will be picked up by retryWhen throw val; } return val; }), retryWhen(errors => errors.pipe( // log error message tap(val => console.log(`Response was missing something`)), ) ) );

No es ideal ya que necesita un contador en el ámbito externo, pero hasta que haya una solución mejor (especialmente sin reintentos basados en el tiempo), esto debería funcionar.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!