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

212
Views
La cadena rxjs se puede activar en paralelo, pero la lógica interna debe ser síncrona (.next con concat)

Los campos en mi caso se pueden finalizar (se ejecutaron acciones vinculadas a un campo). Cuando terminen, necesito actualizar 2 listas:

  • campos ya ejecutados: cadena [] --> matriz simple
  • restingFieldsToExecute: BehaviorSubject<string[]> --> sujeto de comportamiento, porque un .next necesita activar otra lógica. Esta lógica se puede activar en paralelo, pero quiero evitarlo porque hay un empalme dentro de esta lógica que puede comportarse incorrectamente en ese momento. (empalmando un índice, que se eliminó en la cadena paralela).

Entonces, cuando un campo necesita ser finalizado, llamo:

 this.finalize$.next(field);

Y la cadena finalize$ se ve así:

 this.finalize$.pipe( concatMap((field: string) => { return new Promise<void>((resolve) => { console.log('START', field); this.alreadyExecutedFields.push(field); const remainingFieldsToExecute = this.remainingFieldsToExecute$.value; remainingFieldsToExecute.splice(remainingFieldsToExecute.indexOf(field), 1); this.remainingFieldsToExecute$.next(remainingFieldsToExecute); console.log('END', field); resolve(); }); }), ).subscribe(() => { });

Pero por alguna razón, cuando 2 llamadas finalize$.next suceden una después de la otra, concatMap no espera la promesa de la anterior. Además, cuando traté de poner un tiempo de espera alrededor del registro END y la resolución, no espera la resolución anterior.

Lo que sí funciona en mi caso es, en lugar de usar un concatMap, usar un setInterval con una bandera, que bloquea la parte del código donde se actualizan las listas.

Pero, ¿cómo se puede hacer esto de una mejor manera? O de forma correcta con o sin tubos concat.

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

0

  1. para modificar alreadyExecutedFields ya ejecutados, puede usar el operador de tap que se usó para los efectos secundarios
  2. para extraer valor de los campos remainingFieldsToExecute para ejecutar, puede usar withLatestFrom
  3. luego, para modificar los campos remainingFieldsToExecute para ejecutar; puede volver a usar tap
 alreadyExecutedFields: string[] = []; remainingFieldsToExecute$: BehaviorSubject<string[]> = new BehaviorSubject< string[] >(['1', '2', '3', '4', '5']); finalize$ = new BehaviorSubject('1'); ngOnInit() { this.finalize$ .pipe( tap(field => this.alreadyExecutedFields.push(field)), withLatestFrom(this.remainingFieldsToExecute$), tap(([field, remainings]) => { remainings.splice(remainings.indexOf(field), 1); this.remainingFieldsToExecute$.next(remainings); }) ) .subscribe(([_, data]) => { console.group(); console.log('*** NEW EMIT ***'); console.log('current field:', _); console.log('remainingFieldsToExecute', data); console.log('alreadyExecutedFields:', this.alreadyExecutedFields); console.groupEnd(); }); this.finalize$.next('2'); this.finalize$.next('3'); }

demostración: https://stackblitz.com/edit/angular-ivy-ensh7w?file=src/app/app.component.ts

registros:

ingrese la descripción de la imagen aquí

Podría simplificarse a:

 this.finalize$ .pipe( mergeMap(field => this.remainingFieldsToExecute$.pipe( map(remFields => { this.alreadyExecutedFields.push(field); remFields.splice(remFields.indexOf(field), 1); return remFields; }) ) ) ) .subscribe()
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!