Diferencia entre estrangular y eliminar el rebote de una función

251

¿Alguien puede darme una explicación en palabras simples sobre la diferencia entre estrangular y eliminar el rebote de una función con fines de limitación de velocidad?

Para mí, ambos parecen hacer lo mismo. He revisado estos dos blogs para descubrir:

http://remysharp.com/2010/07/21/throttling-function-calls

http://benalman.com/projects/jquery-throttle-debounce-plugin/

bhavya_w
fuente
102
demo.nimius.net/debounce_throttle es una visualización buena
thriqon
44
@thriqon esa visualización es mejor que mi descripción.
Donal
Sí, eso también me ayudó a entender este concepto ... +1 para el autor original ;-)
thriqon
Un ejemplo muy simple que me ayudó a entender. jsfiddle.net/Voronar/sxjy25ew/1
Kirill A. Khalitov
1
Puede ver la visualización aquí también codepen.io/chriscoyier/pen/vOZNQV
trungk18

Respuestas:

346

Para decirlo en términos simples:

  • La limitación retrasará la ejecución de una función. Reducirá las notificaciones de un evento que se dispara varias veces.
  • El rebote agrupará una serie de llamadas secuenciales a una función en una sola llamada a esa función. Asegura que se realiza una notificación para un evento que se dispara varias veces.

Puedes ver la diferencia visualmente aquí

Si tiene una función que se llama mucho, por ejemplo, cuando se produce un evento de cambio de tamaño o movimiento del mouse, se puede llamar muchas veces. Si no desea este comportamiento, puede limitarlo para que se llame a la función a intervalos regulares. El rebote significará que se llama al final (o inicio) de un grupo de eventos.

Donal
fuente
99
Creo que el enlace de visualización de thriqon muestra cómo funciona muy bien. Si tiene una función que se llama mucho, por ejemplo, cuando ocurre un evento de cambio de tamaño o movimiento del mouse, se puede llamar muchas veces. Si no quiere esto, puede estrangularlo para que se llame a la función a intervalos regulares. El rebote significará que se llama al final (o inicio) de un grupo de llamadas.
Donal
10
@AdamM. Eche un vistazo a la visualización aquí: demo.nimius.net/debounce_throttle
Donal
2
@AdamM. No. Puede visualizar esto moviendo el mouse en la demostración y deteniendo el movimiento del mouse de vez en cuando. La barra antirrebote "marcará" después de que haya detenido todo el movimiento del mouse, mientras que la barra del acelerador seguirá "marcando" mientras el mouse se mueve, pero a una velocidad reducida (estrangulada).
John Weisz
26
Absolutamente me encanta la visualización. ¡Gracias!
Sammi
44
El enlace es más valioso que las mil palabras
Finesse
148

Personalmente, encontré que el rebote es más difícil de comprender que el acelerador .

Como ambas funciones le ayudan a posponer y reducir la tasa de ejecución. Suponiendo que está llamando a funciones decoradas devueltas por el acelerador / antirrebote repetidamente ...

  • Acelerador : la función original se llamará como máximo una vez por período especificado.
  • Debounce : se llama a la función original después de que la persona que llama deja de llamar a la función decorada después de un período específico .

Encontré que la última parte de rebote es crucial para comprender el objetivo que está tratando de lograr. También encontré una versión anterior de la implementación de _.debounce que ayuda a la comprensión (cortesía de https://davidwalsh.name/function-debounce ).

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};

Una metáfora descabellada, pero quizás también podría ayudar.

Tienes una amiga llamada Chatty a la que le gusta hablar contigo por mensajería instantánea. Suponiendo que cuando habla, envía un nuevo mensaje cada 5 segundos, mientras que el ícono de la aplicación de MI rebota hacia arriba y hacia abajo, puede tomar el ...

  • Enfoque ingenuo : verifique cada mensaje siempre que llegue. Cuando el ícono de su aplicación rebota, verifique. No es la forma más efectiva, pero siempre estás actualizado.
  • Enfoque del acelerador : verifica una vez cada 5 minutos (cuando hay nuevos). Cuando llegue un nuevo mensaje, si lo ha verificado en cualquier momento en los últimos 5 minutos, ignórelo. Ahorras tu tiempo con este enfoque, mientras sigues en el ciclo.
  • Enfoque de rebote : ya sabes Chatty, ella divide una historia completa en pedazos, los envía en un mensaje tras otro. Esperas hasta que Chatty termine toda la historia: si deja de enviar mensajes durante 5 minutos, asumirías que ha terminado, ahora revisas todo.
Dapeng Li
fuente
17
No entendí la diferencia entre estas 2 funciones hasta que leí esto. Gracias
Seamus Barrett
77
La metáfora es uno de los mejores ejemplos que he leído sobre el acelerador y el rebote. Gracias.
Vignesh
96

Las diferencias

+--------------+-------------------+-------------------+
|              |  Throttle 1 sec   |  Debounce 1 sec   |
+--------------+-------------------+-------------------+
| Delay        | no delay          | 1 sec delay       |
|              |                   |                   |
| Emits new if | last was emitted  | there is no input |
|              | before 1 sec      |  in last 1 sec    |
+--------------+-------------------+-------------------+

Explicación por caso de uso :

  • Barra de búsqueda: ¿no desea buscar cada vez que el usuario presiona la tecla? Desea buscar cuando el usuario dejó de escribir durante 1 segundo. Use debounce1 seg al presionar la tecla.

  • Juego de disparos: la pistola toma 1 segundo de tiempo entre cada disparo, pero el usuario hace clic con el mouse varias veces. Usar throttlecon el clic del mouse.

Invertir sus roles :

  • Aceleración de 1 segundo en la barra de búsqueda : si los usuarios escriben abcdefghijcon cada carácter 0.6 sec. Luego, el acelerador se disparará a la primera apresión. Ignorará cada pulsación durante el siguiente 1 segundo, es decir, ba .6 segundos se ignorará. Luego, ca los 1.2 segundos, se activará nuevamente, lo que restablece el tiempo nuevamente. Por dlo tanto , se ignorará y ese activará.

  • Pistola rebotando durante 1 segundo: cuando el usuario ve a un enemigo, hace clic con el mouse, pero no disparará. Volverá a hacer clic varias veces en ese segundo, pero no disparará. Verá si todavía tiene balas, en ese momento (1 segundo después del último clic) la pistola se disparará automáticamente.

amit77309
fuente
37

La limitación impone un número máximo de veces que se puede invocar una función a lo largo del tiempo. Como en "ejecutar esta función como máximo una vez cada 100 milisegundos".

El rebote obliga a que no se vuelva a llamar a una función hasta que haya transcurrido una cierta cantidad de tiempo sin que se llame. Como en "ejecutar esta función solo si han pasado 100 milisegundos sin que se llame".

árbitro

Anshul
fuente
20

Acelerador (1 seg.): Hola, soy un robot. Mientras me sigas haciendo ping, seguiré hablando contigo, pero después de exactamente 1 segundo cada uno. Si me envía una respuesta antes de que transcurra un segundo, todavía le responderé exactamente en un intervalo de 1 segundo. En otras palabras, me encanta responder a intervalos exactos.

Debounce (1 sec): Hola, soy ese ^^ primo del robot. Mientras me sigas haciendo ping, me quedaré en silencio porque me gusta responder solo después de que haya pasado 1 segundo desde la última vez que me pinchaste . No sé si es porque tengo un problema de actitud o porque simplemente no me gusta interrumpir a las personas. En otras palabras, si sigue pidiéndome respuestas antes de que transcurra 1 segundo desde su última invocación, nunca recibirá una respuesta. Sí, sí ... ¡adelante! llamame grosero


Acelerador (10 min): soy una máquina de registro. Envío registros del sistema a nuestro servidor de fondo, después de un intervalo regular de 10 minutos.

Debounce (10 sec): Hola, no soy primo de esa máquina de registro. (No todos los rebotadores están relacionados con un estrangulador en este mundo imaginario). Trabajo como mesero en un restaurante cercano. Debo hacerle saber que mientras siga agregando cosas a su orden, no iré a la cocina para ejecutar su orden. Solo cuando hayan transcurrido 10 segundos desde la última vez que modificó su pedido, asumiré que ha terminado con su pedido. Solo entonces ejecutaré tu orden en la cocina.


Demostraciones interesantes: https://css-tricks.com/debouncing-throttling-explained-examples/

Créditos para la analogía del camarero: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf

Usman
fuente
1
La mejor explicación.
Karan Sharma
17

El rebote le permite administrar la frecuencia de las llamadas que puede recibir una función. Combina varias llamadas que suceden en una función determinada, de modo que se ignoran las llamadas repetidas que ocurren antes de que expire un período de tiempo específico. Básicamente, la eliminación de rebotes garantiza que se envíe exactamente una señal para un evento que puede estar ocurriendo varias veces.

La limitación restringe la frecuencia de las llamadas que recibe una función a un intervalo de tiempo fijo. Se utiliza para garantizar que la función de destino no se invoque con más frecuencia que el retraso especificado. La limitación es la reducción en la tasa de un evento repetitivo.

GibboK
fuente
17

Es sencillo.

Hacen exactamente lo mismo (limitación de velocidad), excepto que mientras se llama el acelerador , activará su función envuelta periódicamente, y el rebote no lo hará. Debounce solo (intenta) llamar a su función una vez al final.

Ejemplo : si está desplazándose, el acelerador llamará lentamente a su función mientras se desplaza (cada X milisegundos). Debounce esperará hasta que hayas terminado de desplazarte para llamar a tu función.

Ryan Taylor
fuente
Vale la pena señalar que en estas demostraciones, puede que no se vean "idénticas" porque el rebote siempre disparará X milisegundos después del último evento, mientras que la última llamada del acelerador puede ocurrir antes (y no es necesario volver a llamar cuando normalmente se dispara el rebote) ) es bastante intrascendente, pero vale la pena mencionarlo si miras las demos.
Ryan Taylor
16

En términos simples:

El rebote evitará que una función se ejecute mientras todavía se llama con frecuencia. Una función sin rebote solo se ejecutará después de que se haya determinado que ya no se llama, en cuyo momento se ejecutará exactamente una vez. Ejemplos prácticos de eliminación de rebotes:

  • Guardar o validar automáticamente el contenido de un campo de texto si el usuario "dejó de escribir": la operación solo se realizará una vez, DESPUÉS de que se haya determinado que el usuario ya no está escribiendo (ya no presiona teclas).

  • Registro donde los usuarios descansan el mouse: el usuario ya no mueve el mouse, por lo que se puede registrar la (última) posición.

La limitación simplemente evitará que una función se ejecute si se ha ejecutado recientemente, independientemente de la frecuencia de la llamada. Ejemplos prácticos de estrangulamiento:

  • Las implementaciones de v-sync se basan en la limitación: la pantalla solo se dibujará si transcurrieron 16 ms desde el último sorteo de la pantalla. No importa cuántas veces se llame a la funcionalidad de actualización de pantalla, solo se ejecutará como máximo una vez cada 16 ms.
John Weisz
fuente
7

Una analogía de la vida real que personalmente me ayuda a recordar:

  • debounce = una conversación . esperas a que la otra persona termine de hablar antes de responder.
  • acelerador = un bit de tambor . solo toca notas en un simple bit de batería de 4/4.

Casos de uso para el rebote :

  • Mecanografía. Desea hacer algo después de que el usuario dejó de escribir. Entonces, esperar 1 segundo después de la última pulsación de tecla tiene sentido. Cada pulsación de tecla reinicia la espera.
  • Animación. Desea reducir un elemento una vez que el usuario dejó de desplazarse sobre él. No usar el rebote puede causar una animación errática como resultado del movimiento involuntario del cursor entre las zonas "caliente" y "fría".

Casos de uso para el acelerador :

  • Desplazamiento Desea reaccionar al desplazamiento pero limitar la cantidad de cálculos realizados, por lo que hacer algo cada 100 ms es suficiente para evitar posibles retrasos.
  • Movimiento del ratón. Igual que el desplazamiento pero para mover el mouse.
  • Llamadas a la API Desea activar una llamada a la API en ciertos eventos de la interfaz de usuario, pero desea limitar la cantidad de llamadas a la API que realiza para no sobrecargar su servidor.
Chico
fuente
4

Throtle es solo una envoltura alrededor de la función antirrebote que hace que la función antirrebote pase functionen un período de tiempo, si la función antirrebote retrasa una llamada de función en un período de tiempo que es mayor que el especificado en aceleración .

Oleg Tsyba
fuente
2

Estrangulamiento

La limitación impone un número máximo de veces que una función se puede llamar horas extras. Como en "ejecutar esta función como máximo una vez cada 100 milisegundos". Digamos que en circunstancias normales llamaría a esta función 1,000 veces durante 10 segundos. Si lo limita solo una vez por cada 100 milisegundos, solo ejecutará esa función como máximo 100 veces

(10s * 1,000) = 10,000ms
10,000ms / 100ms throttling = 100 maximum calls

Rebotando

El rebote obliga a que no se vuelva a llamar a una función hasta que haya transcurrido un cierto tiempo sin que se llame. Como en "ejecutar esta función solo si han pasado 100 milisegundos sin que se llame".

Quizás una función se llama 1,000 veces en una ráfaga rápida, se dispersa en 3 segundos y luego deja de llamarse. Si lo ha eliminado en 100 milisegundos, la función solo se activará una vez, a los 3,1 segundos, una vez que finalice la ráfaga. Cada vez que se llama a la función durante la ráfaga, se restablece el temporizador antirrebote

fuente: - acelerador y rebote

bajran
fuente
2

Supongamos que tenemos una función de devolución de llamada "cb" que se llamará en el evento "E". Deje que "E" se active 1000 veces en 1 segundo, por lo tanto, habría 1000 llamadas a "cb". Eso es 1 llamada / ms. Para optimizar podemos usar:

  • Aceleración : con la aceleración de (100ms), se llamaría "cb" en [100 ms, 200 ms, 300 ms, ... 1000 ms]. Eso es 1 llamada / 100 ms. Aquí 1000 llamadas a "cb" optimizadas para 10 llamadas.
  • Rebote : con el rebote de (100 ms), "cb" se llamaría solo una vez el [1100 seg.]. Eso es 100 ms después del último desencadenante de "E" que sucedió en [1000 ms]. Aquí 1000 llamadas a "cb" optimizadas para 1 llamada.
Nat Geo
fuente
1

Por lo que entiendo, en términos simples Regulación: similar a llamar a setInterval (devolución de llamada) durante un cierto número de veces, es decir, llamar a la misma función durante un cierto número de veces a lo largo del tiempo al producirse un evento y ... Debouncing: similar a llamar a setTImeout (callbackForApi) o llamar a una función después de que haya pasado cierto tiempo en caso de ocurrencia del evento. Este enlace puede ser útil: https://css-tricks.com/the-difference-between-throttling-and-debouncing/

Pranay Binju
fuente