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

239
Views
¿Cómo puedo determinar el número de valores que se han emitido durante el tiempo de rebote?

Dado:

Un efecto NgRx que maneja una solicitud para "acercar" una pantalla. Recibe una notificación cada vez que los usuarios hacen clic en un botón apropiado.

 public readonly zoomIn$ = createEffect( () => this.actions$.pipe( ofType(zoomIn), tap(() => { scale(); }), ), { dispatch: false }, );

Nota: La acción zoomIn no pudo y no contiene ninguna carga útil. Considéralo solo como un disparador

Problema:

El redibujado cuesta recursos y en algunos casos toma unos segundos para obtener una nueva escala. Entonces, si desea escalar varias veces seguidas, se verá obligado a esperar.

Solución:

Al usar el operador debounceTime , posponga la llamada de la función scale() y espere hasta que los usuarios hagan varios clics. Suena bien. El único problema es que debounceTime nos notifica el último valor. Y lo que necesitamos es una cantidad de valores (clics del usuario) silenciados por el operador debounceTime .

En una vista más general, la tarea suena como: ¿cómo calcular el recuento de valores emitidos por el flujo de origen y silenciados por el operador debounceTime ?

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

0

Mi solución es crear un operador canalizable personalizado que logre el objetivo.

¿Qué necesitamos? Por supuesto, necesitamos un operador debounceTime .

 .pipe( debounceTime(300), )

Luego debemos calcular el número de valores que se han emitido. Hay un operador de scan que se parece bastante a una conocida función de reduce . Le daremos un valor inicial y aumentaremos un contador en cada valor recibido del flujo de origen. Tenemos que colocarlo antes del operador debounceTime . Ahora parece una secuencia de índices.

 .pipe( scan(acc => acc + 1, 0), debounceTime(300), )

Cuando debounceTime nos notifica el último índice, ¿cómo podemos saber la cantidad de valores silenciados? Tenemos que compararlo con el índice anterior que se ha emitido. El valor anterior se puede recibir utilizando un operador por pairwise . Y luego obtenga una diferencia entre ellos usando el operador de map .

 .pipe( scan(acc => acc + 1, 0), debounceTime(300), pairwise(), map(([previous, current]) => current - previous), )

Si intenta esto en el estado actual, notará que algo anda mal, que no funciona por primera vez. El problema radica en el operador pairwise . Emite pares de valores (anterior y actual), por lo que espera a tener al menos dos valores antes de iniciar la emisión de pares. ¿Es justo? ¿Sí, lo es? Es por eso que necesitamos hacer un poco de trampa y proporcionar un primer valor (es decir, 0), con el uso del operador startWith .

La implementación final

 /** * Emits a notification from the source Observable only after a particular time span has passed without another source emission, * with an exact number of values were emitted during that time. * * @param dueTime the timeout duration in milliseconds for the window of time required to wait for emission silence before emitting the most recent source value. * @returns MonoTypeOperatorFunction */ export const debounceCounter = (dueTime: number): MonoTypeOperatorFunction<number> => (source: Observable<unknown>): Observable<number> => new Observable(observer => source .pipe( scan(acc => acc + 1, 0), debounceTime(dueTime), startWith(0), pairwise(), map(([previous, current]) => current - previous), ) .subscribe({ next: x => { observer.next(x); }, error: err => { observer.error(err); }, complete: () => { observer.complete(); }, }), );

ejemplo de uso

 public readonly zoomIn$ = createEffect( () => this.actions$.pipe( ofType(zoomIn), debounceCounter(300), tap(times => { // scale n-times }), ), { dispatch: false }, );
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!