Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

232
Vistas
¿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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda