Różnica między ograniczaniem a ogłaszaniem funkcji

250

Czy ktoś może mi w prosty sposób wyjaśnić różnicę między ograniczaniem a ogłaszaniem funkcji w celu ograniczenia prędkości.

Wydaje mi się, że oboje robią to samo. Sprawdziłem te dwa blogi, aby się dowiedzieć:

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

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

bhavya_w
źródło
102
demo.nimius.net/debounce_throttle to dobra wizualizacja
thriqon
4
@ thriqon, że wizualizacja jest lepsza niż mój opis.
Donal
Tak, to pomogło mi również zrozumieć tę koncepcję ... +1 dla oryginalnego autora ;-)
thriqon
Bardzo prosty przykład, który pomógł mi zrozumieć. jsfiddle.net/Voronar/sxjy25ew/1
Kirill A. Khalitov
1
Widzę tutaj również wizualizację codepen.io/chriscoyier/pen/vOZNQV
trungk18

Odpowiedzi:

344

Krótko mówiąc:

  • Ograniczanie opóźni wykonanie funkcji. Zmniejszy liczbę powiadomień o zdarzeniu, które jest uruchamiane wiele razy.
  • Odwołanie spowoduje zebranie serii kolejnych wywołań funkcji w jedno wywołanie tej funkcji. Zapewnia to, że jedno zdarzenie zostanie wygenerowane wielokrotnie.

Można naocznie zobaczyć różnicę tutaj

Jeśli masz funkcję, która jest często wywoływana - na przykład, gdy występuje zdarzenie zmiany rozmiaru lub ruchu myszy, można ją wywołać wiele razy. Jeśli nie chcesz tego zachowania można Przepustnica go tak, że funkcja jest wywoływana w regularnych odstępach czasu. Ogłoszenie oznacza, że ​​jest wywoływane na końcu (lub na początku) szeregu zdarzeń.

Donal
źródło
9
Myślę, że link do wizualizacji Thriqon pokazuje, jak to działa bardzo dobrze. Jeśli masz funkcję, która jest często wywoływana - na przykład, gdy występuje zdarzenie zmiany rozmiaru lub ruchu myszy, można ją wywołać wiele razy. Jeśli nie chcesz tego, możesz go dławić, aby funkcja była wywoływana w regularnych odstępach czasu. Ogłaszanie oznacza, że ​​jest wywoływane na końcu (lub na początku) szeregu połączeń.
Donal
10
@AdamM. Spójrz na wizualizację tutaj: demo.nimius.net/debounce_throttle
Donal
2
@AdamM. Nie. Możesz to sobie wyobrazić, przesuwając mysz w wersji demonstracyjnej i co jakiś czas zatrzymując ruch myszy. Pasek odbicia będzie „tykał ” po zatrzymaniu całego ruchu myszy, podczas gdy pasek przepustnicy będzie nadal „tykał” podczas ruchu myszy, ale ze zmniejszoną (dławioną) prędkością.
John Weisz
26
Absolutnie lubię wizualizację. Dzięki!
Sammi
4
Link jest cenniejszy niż tysiąc słów
Finezja
148

Osobiście uważałem, że debounce jest trudniejsze do zrozumienia niż przepustnica .

Ponieważ obie funkcje pomagają odłożyć w czasie i zmniejszyć szybkość niektórych operacji. Zakładając, że wywołujesz funkcje ozdobne zwracane przez przepustnicę / debounce wielokrotnie ...

  • Przepustnica : oryginalna funkcja może być wywoływana maksymalnie raz na określony czas.
  • Debounce : oryginalna funkcja zostanie wywołana po tym, jak osoba dzwoniąca przestanie wywoływać dekorowaną funkcję po określonym czasie .

Uważam, że ostatnia część debaty jest kluczowa dla zrozumienia celu, który próbuje osiągnąć. Znalazłem też starą wersję implementacji _.debounce, która pomaga zrozumieć (dzięki uprzejmości 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);
  };
};

Niejasna metafora, ale może też może pomóc.

Masz znajomego o imieniu Chatty, który lubi z tobą rozmawiać przez komunikator. Zakładając, że kiedy mówi, wysyła nową wiadomość co 5 sekund, a ikona aplikacji czatu przesuwa się w górę iw dół, możesz ...

  • Naiwne podejście: sprawdzaj każdą wiadomość, dopóki ona dotrze. Gdy ikona aplikacji podskoczy, sprawdź. To nie jest najskuteczniejszy sposób, ale zawsze jesteś na bieżąco.
  • Podejście przepustnicy : sprawdzasz raz na 5 minut (gdy są nowe). Gdy nadejdzie nowa wiadomość, jeśli sprawdziłeś ją w ciągu ostatnich 5 minut, zignoruj ​​ją. Dzięki takiemu podejściu oszczędzasz czas, będąc ciągle w pętli.
  • Podejście do debugowania : znasz Chatty, ona rozkłada całą historię na części, wysyła je jedna po drugiej. Poczekaj, aż Chatty skończy całą historię: jeśli przestanie wysyłać wiadomości na 5 minut, możesz założyć, że skończyła, teraz sprawdzasz wszystko.
Dapeng Li
źródło
17
Nie zrozumiałem różnicy między tymi 2 funkcjami, dopóki tego nie przeczytałem. Dzięki
Seamus Barrett
7
Metafora jest jednym z największych przykładów, jakie kiedykolwiek czytałem o przepustnicy i debazie. Dzięki.
Vignesh,
96

Różnice

+--------------+-------------------+-------------------+
|              |  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    |
+--------------+-------------------+-------------------+

Objaśnienie według przypadku użycia :

  • Pasek wyszukiwania - nie chcesz wyszukiwać za każdym razem, gdy użytkownik naciska klawisz? Chcesz wyszukać, gdy użytkownik przestał pisać na 1 sekundę. Użyj debounce1 sekundy po naciśnięciu klawisza.

  • Strzelanie - pistolet trwa 1 sekundę między każdym strzałem, ale użytkownik kliknie myszą wiele razy. Użyj throttlepo kliknięciu myszą.

Odwracanie ich ról :

  • Ograniczanie 1 sek. Na pasku wyszukiwania - jeśli użytkownicy wpisują abcdefghijkażdą postać 0.6 sec. Następnie przepustnica uruchomi się przy pierwszym anaciśnięciu. Będzie ignorował każde naciśnięcie przez następną 1 sekundę, tj. bPrzy 0,6 sekundy zostanie zignorowany. Następnie cpo 1,2 sek ponownie uruchomi się, co ponownie wyzeruje czas. dZostaną więc zignorowane i ezostaną uruchomione.

  • Ogłaszając pistolet na 1 sekundę - Gdy użytkownik zobaczy wroga, klika myszką, ale nie strzela. Kliknie ponownie kilka razy w tej sekundzie, ale nie będzie strzelać. Zobaczy, czy nadal ma pociski, w tym czasie (1 sekundę po ostatnim kliknięciu) pistolet będzie strzelał automatycznie.

amit77309
źródło
37

Ograniczanie wymusza maksymalną liczbę wywołań funkcji w czasie. Jak w „wykonaj tę funkcję co najwyżej raz na 100 milisekund”.

Odwołanie wymusza, aby funkcja nie była wywoływana ponownie, dopóki upłynie określony czas bez jej wywołania. Jak w „wykonaj tę funkcję tylko wtedy, gdy minęło 100 milisekund bez wywołania”.

ref

Anszul
źródło
20

Przepustnica (1 sek): Cześć, jestem robotem. Tak długo, jak będziesz mnie pingować, będę z tobą rozmawiać, ale po dokładnie 1 sekundzie. Jeśli wyślesz mi ping do odpowiedzi, zanim upłynie sekunda, nadal będę odpowiadać ci dokładnie co 1 sekundę. Innymi słowy, po prostu uwielbiam odpowiadać w dokładnych odstępach czasu.

Debounce (1 sec): Cześć, jestem kuzynem robota ^^. Tak długo, jak będziesz pingował mnie, będę milczeć, ponieważ lubię odpowiadać dopiero po upływie 1 sekundy od ostatniego pingowania mnie . Nie wiem, czy to dlatego, że mam problem z postawą, czy po prostu nie lubię przeszkadzać ludziom. Innymi słowy, jeśli będziesz prosił mnie o odpowiedzi przed upływem 1 sekundy od ostatniego wywołania, nigdy nie otrzymasz odpowiedzi. Tak, tak ... śmiało! nazywaj mnie niegrzecznym.


Przepustnica (10 min): Jestem maszyną do pozyskiwania drewna. Wysyłam dzienniki systemowe do naszego serwera zaplecza, po regularnych odstępach 10 minut.

Debounce (10 sec): Cześć, nie jestem kuzynem tej maszyny do logowania. (Nie każdy debiutant jest powiązany z przepustnicą w tym wymyślonym świecie). Pracuję jako kelner w pobliskiej restauracji. Powinienem poinformować cię, że dopóki będziesz dodawać rzeczy do swojego zamówienia, nie pójdę do kuchni w celu wykonania twojego zamówienia. Dopiero po upływie 10 sekund od ostatniej modyfikacji zamówienia założę, że zamówienie zostało zakończone. Dopiero wtedy zrealizuję twoje zamówienie w kuchni.


Fajne dema: https://css-tricks.com/debouncing-throttling-explained-examples/

Kredyty dla analogii kelnera: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf

Usman
źródło
1
najlepsze wytłumaczenie.
Karan Sharma
17

Funkcja ogłaszania umożliwia zarządzanie częstotliwością połączeń odbieranych przez funkcję. Łączy wiele wywołań, które występują w danej funkcji, dzięki czemu powtarzane połączenia, które występują przed upływem określonego czasu, są ignorowane. Zasadniczo ogłaszanie zapewnia wysłanie dokładnie jednego sygnału dla zdarzenia, które może wystąpić kilka razy.

Dławienie ogranicza częstotliwość połączeń, że funkcja otrzymuje z ustalonym przedziale czasowym. Służy do zapewnienia, że ​​funkcja docelowa nie będzie wywoływana częściej niż określone opóźnienie. Ograniczanie to zmniejszenie częstości powtarzających się zdarzeń.

GibboK
źródło
17

To proste.

Robią dokładnie to samo (ograniczenie prędkości), z wyjątkiem sytuacji, gdy wywoływana jest przepustnica, będzie ona okresowo uruchamiała twoją zawiniętą funkcję, a debounce nie. Debounce po prostu (próbuje) wywołać twoją funkcję raz na samym końcu.

Przykład : Jeśli przewijasz, przepustnica będzie powoli wywoływać twoją funkcję podczas przewijania (co X milisekund). Debounce poczeka, aż skończysz przewijanie, aby wywołać twoją funkcję.

Ryan Taylor
źródło
warto zauważyć, że w tych wersjach demonstracyjnych mogą nie wyglądać „identycznie”, ponieważ debounce zawsze wyzwala X milisekund po ostatnim zdarzeniu, podczas gdy ostatnie wywołanie przepustnicy może nastąpić wcześniej (i nie trzeba go ponownie wywoływać, gdy debounce normalnie strzela ). jest to dość nieistotne, ale warto wspomnieć, jeśli spojrzysz na dema.
Ryan Taylor
16

W kategoriach laika:

Odwołanie uniemożliwi działanie funkcji, gdy jest ona często wywoływana. Zadeklarowana funkcja będzie działać dopiero po ustaleniu, że nie jest już wywoływana, w którym to momencie uruchomi się dokładnie raz. Praktyczne przykłady ogłaszania:

  • Automatyczne zapisywanie lub sprawdzanie poprawności zawartości pola tekstowego, jeśli użytkownik „przestał pisać”: operacja zostanie wykonana tylko raz, PO ustaleniu, że użytkownik nie pisze już (nie naciska już klawiszy).

  • Rejestrowanie w miejscu, gdzie użytkownicy spoczywają na myszy: użytkownik nie porusza już myszą, dzięki czemu można zapisać (ostatnią) pozycję.

Ograniczanie po prostu uniemożliwi uruchamianie funkcji, jeśli ostatnio działała, niezależnie od częstotliwości wywołań. Praktyczne przykłady ograniczania:

  • Implementacje synchronizacji pionowej oparte są na ograniczeniu: ekran zostanie narysowany tylko wtedy, gdy upłynie 16 ms od ostatniego losowania ekranu. Bez względu na to, ile razy wywoływana jest funkcja odświeżania ekranu, będzie ona działać najwyżej raz na 16 ms.
John Weisz
źródło
7

Prawdziwa analogia, która osobiście pomaga mi zapamiętać:

  • debounce = rozmowa . czekasz, aż druga osoba skończy mówić, zanim odpowiesz.
  • przepustnica = bit bębna . grasz nuty tylko na prostym bębnie 4/4.

Przypadki użycia do debounce :

  • Pisanie na maszynie. Chcesz coś zrobić, gdy użytkownik przestanie pisać. Dlatego odczekanie 1 sekundy po ostatnim naciśnięciu klawisza ma sens. Każde naciśnięcie klawisza ponownie uruchamia oczekiwanie.
  • Animacja. Chcesz zmniejszyć element, gdy użytkownik przestanie nad nim unosić się. Nieużywanie odbicia może spowodować błędną animację w wyniku niezamierzonego przesunięcia kursora między strefami „gorącą” i „zimną”.

Przypadki użycia przepustnicy :

  • Przewijanie Chcesz reagować na przewijanie, ale ogranicz liczbę wykonanych obliczeń, więc robienie czegoś co 100 ms wystarczy, aby zapobiec potencjalnemu opóźnieniu.
  • Ruch myszy To samo co przewijanie, ale do poruszania myszą.
  • Wywołania API Chcesz wywołać wywołanie API dla niektórych zdarzeń interfejsu użytkownika, ale chcesz ograniczyć liczbę wywołań API, aby nie przeciążać serwera.
Chłopak
źródło
4

throtle jest tylko nakładką na opóźnieniu na co sprawia nieczułości telefonowania przeszedł functionw pewnym okresie czasu, jeśli nieczułości opóźnia wywołanie funkcji na okres czasu, który jest większy niż określony w throtle .

Oleg Tsyba
źródło
2

Dławienie

Ograniczanie wymusza maksymalną liczbę wywołań funkcji w godzinach nadliczbowych. Jak w „wykonaj tę funkcję co najwyżej raz na 100 milisekund”. Powiedz, że w normalnych okolicznościach wywołałeś tę funkcję 1000 razy w ciągu 10 sekund. Jeśli dławisz go tylko raz na 100 milisekund, wykona tę funkcję maksymalnie 100 razy

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

Ogłaszając

Odwołanie wymusza, aby funkcja nie była wywoływana ponownie, dopóki upłynie określony czas bez jej wywołania. Jak w „wykonaj tę funkcję tylko wtedy, gdy minęło 100 milisekund bez wywołania”.

Być może funkcja jest wywoływana 1000 razy w szybkiej serii, rozproszona na 3 sekundy, a następnie przestaje być wywoływana. Jeśli zadebiutowałeś w 100 milisekundach, funkcja uruchomi się tylko raz, w 3,1 sekundy, po zakończeniu serii. Za każdym razem, gdy funkcja jest wywoływana podczas serii, resetuje licznik ogłaszający

źródło: - przepustnica i zapowiedź

bajran
źródło
2

Załóżmy, że mamy funkcję zwrotną „cb”, która ma być wywoływana w przypadku zdarzenia „E”. Niech „E” zostanie wywołane 1000 razy w ciągu 1 sekundy, stąd będzie 1000 połączeń z „cb”. To jest 1 rozmowa / ms. Aby zoptymalizować, możemy użyć:

  • Ograniczanie : Przy ograniczeniu (100ms), „cb” będzie wywoływane [100 ms, 200 ms, 300 ms, ... 1000 ms]. To jest 1 rozmowa / 100 ms. Tutaj 1000 połączeń z „cb” zoptymalizowanych do 10 połączeń.
  • Debouncing : W przypadku ogłaszania (100ms), „cb” będzie wywoływane tylko raz w [1100th sec]. To jest 100 ms po ostatnim wyzwoleniu „E”, które wydarzyło się w [1000. ms]. Tutaj 1000 połączeń z „cb” zoptymalizowanych do 1 połączenia.
Nat Geo
źródło
1

O ile rozumiem, w prostych słowach Ograniczanie - podobne do wywoływania setInterval (oddzwanianie) przez określoną liczbę razy, tj. Wywoływanie tej samej funkcji przez określoną liczbę razy w czasie po wystąpieniu zdarzenia i .. Ogłoszenie - podobne do wywoływania setTImeout (callbackForApi) lub wywołanie funkcji po upływie określonego czasu od wystąpienia zdarzenia. Ten link może być pomocny- https://css-tricks.com/the-difference-between-throttling-and-debouncing/

Pranay Binju
źródło