Bir işlevi azaltma ve geri alma arasındaki fark


252

Herkes hız azaltma amacıyla bir işlevi azaltma ve bir işlevi geri alma arasındaki fark hakkında basit bir açıklama yapabilir mi?

Bana göre her ikisi de aynı şeyi yapıyor. Öğrenmek için bu iki blogu inceledim:

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

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


102
demo.nimius.net/debounce_throttle iyi bir görselleştirme
thriqon

4
@thriqon görselleştirmenin benim tanımımdan daha iyi olduğunu.
Donal

Evet, bu da benim bu kavramı anlamama yardımcı oldu ... + 1 orijinal yazar için ;-)
thriqon

Anlamama yardımcı olan çok basit bir örnek. jsfiddle.net/Voronar/sxjy25ew/1
Kirill A. Khalitov

1
Görselleştirmeyi burada da görebilirsiniz codepen.io/chriscoyier/pen/vOZNQV
trungk18

Yanıtlar:


347

Basit bir ifadeyle:

  • Kısma , bir işlevin yürütülmesini geciktirir. Birden çok kez tetiklenen bir etkinliğin bildirimlerini azaltır.
  • Sökme , bir işleve bir dizi ardışık çağrıyı o işleve tek bir çağrıda birleştirir. Birden çok kez tetiklenen bir etkinlik için bir bildirim yapılmasını sağlar.

Farkı görsel olarak burada görebilirsiniz

Çok fazla çağrılan bir fonksiyonunuz varsa - örneğin bir yeniden boyutlandırma veya fare taşıma olayı meydana geldiğinde, çok kez çağrılabilir. Eğer bu davranışı istemiyorsanız şunları yapabilirsiniz kelebeği fonksiyon düzenli aralıklarla çağrılması için bunu. Sönümleme , bir grup etkinliğin sonunda (veya başlangıcında) çağrıldığı anlamına gelir.


9
Bence thriqon'un görselleştirme bağlantısı nasıl çok iyi çalıştığını gösteriyor. Çok fazla çağrılan bir fonksiyonunuz varsa - örneğin bir yeniden boyutlandırma veya fare taşıma olayı meydana geldiğinde, çok kez çağrılabilir. Bunu istemiyorsanız, işlevi düzenli aralıklarla çağırmak için kısıtlayabilirsiniz. Sökme, bir grup çağrının sonunda (veya başında) çağrıldığı anlamına gelir.
Donal

10
@AdamM. Görselleştirmeye bir göz atın: demo.nimius.net/debounce_throttle
Donal

2
@AdamM. Hayır. Farenizi demoda hareket ettirerek ve arada bir fare hareketini durdurarak bunu görselleştirebilirsiniz . Debounce-bar "kene" olacak sonra da tüm fare hareketi durdurdu gaz kelebeği-bar "saatli" tutacak olurken, olurken fare doğru, fakat azaltılmış (throttled) hızında.
John Weisz

26
Görselleştirmeyi kesinlikle çok seviyorum. Teşekkürler!
Sammi

4
Bağlantı bin kelimeden daha değerlidir
Finesse

148

Şahsen ben buldum Sıçrama daha kavrar zor gaz .

Her iki işlev de ertelemenize ve bazı yürütme oranını azaltmanıza yardımcı olur. Tekrar tekrar gaz / geri getirme tarafından döndürülen süslü işlevleri çağırdığınızı varsayarsak ...

  • Gaz kelebeği : Orijinal işlev, belirtilen periyot başına en fazla bir kez çağrılır.
  • Çıkarma : orijinal işlev , arayan belirli bir süre sonra dekore edilmiş işlevi çağırmayı durdurduktan sonra çağrılır .

Geri dönmenin son bölümünü elde etmeye çalıştığı hedefi anlamak için çok önemli buldum. Ayrıca _.debounce uygulamasının eski bir versiyonunun anlaşılmasına yardımcı olduğunu buldum ( https://davidwalsh.name/function-debounce nezaket ).

// 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);
  };
};

Çok getirilmiş bir metafor, ama belki de yardımcı olabilir.

Sohbet yoluyla sizinle konuşmayı seven Chatty adında bir arkadaşınız var. Sohbet ettiğinde, her 5 saniyede bir yeni bir mesaj gönderdiğini varsayarsak, IM uygulama simgeniz yukarı ve aşağı sıçrarken, ...

  • Naif yaklaşım: her mesajı ulaştığı sürece kontrol edin. Uygulama simgeniz sektiğinde kontrol edin. Bu en etkili yol değil, ama her zaman güncelsiniz.
  • Gaz kelebeği yaklaşımı: Her 5 dakikada bir kontrol edin (yenileri olduğunda). Yeni mesaj geldiğinde, son 5 dakika içinde herhangi bir zamanda kontrol ettiyseniz, yok sayın. Halen döngüdeyken bu yaklaşımla zaman kazanırsınız.
  • Debounce yaklaşımı: Chatty'yi biliyorsun, bütün bir hikayeyi parçalara ayırıyor, onları bir mesajda birbiri ardına gönderiyor. Chatty tüm hikayeyi bitirene kadar beklersiniz: 5 dakika boyunca mesaj göndermeyi bırakırsa, bitirdiğini varsayarsınız, şimdi hepsini kontrol edersiniz.

17
Bunu okuyana kadar bu 2 işlev arasındaki farkı anlamadım. Teşekkürler
Seamus Barrett

7
Metafor, gaz ve geri tepme hakkında okuduğum en büyük örnek parçalardan biridir. Teşekkürler.
Vignesh

96

farklılıklar

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

Kullanım durumuna göre açıklama :

  • Arama çubuğu- Kullanıcı tuşa her bastığında arama yapmak istemiyor musunuz? Kullanıcı 1 saniye yazmayı bıraktığında arama yapmak istiyorum. debounceTuşa basarken 1 sn kullanın .

  • Çekim oyunu- Tabanca her çekim arasında 1 saniye sürebilir ama kullanıcı fare birden çok kez tıklatın. throttleFare tıklamasıyla kullanın .

Rollerini tersine çevirmek :

  • Arama çubuğunda 1 sn. Kısma - Kullanıcılar abcdefghijher karakterde yazıyorsa0.6 sec . Ardından gaz ilk abasışta tetiklenir . Sonraki 1 saniye boyunca her basıldığında göz ardı edilecek, yani b.6 saniyede göz ardı edilecektir. Sonra c1.2 saniyede tekrar tetiklenir, bu da zamanı tekrar sıfırlar. Böylece dyok sayılır ve etetiklenir.

  • Tabancayı 1 saniyeliğine kaldırın- Kullanıcı bir düşman gördüğünde fareyi tıklar, ancak ateş etmez. O saniye içinde birkaç kez tekrar tıklayacak ama ateş etmeyecek. Hâlâ mermi olup olmadığını görecek, o sırada (son tıklamadan 1 saniye sonra) tabanca otomatik olarak ateş edecek.


37

Kısma , bir fonksiyonun zaman içinde maksimum sayıda çağrılmasını sağlar. "Bu işlevi en fazla 100 milisaniyede bir kez gerçekleştirin."

Sökme , bir işlevin, çağrılmadan belirli bir süre geçene kadar yeniden çağrılmamasını zorunlu kılar . "Bu işlevi yalnızca 100 milisaniye çağrılmadan geçtiyse" yürütün.

ref


20

Gaz (1 sn): Merhaba, ben bir robotum. Bana ping atmaya devam ettiğiniz sürece, sizinle konuşmaya devam edeceğim, ama her biri tam 1 saniye sonra. Bana bir saniye geçmeden cevap vermek için ping atıyorsanız, size tam olarak 1 saniye arayla cevap vereceğim. Başka bir deyişle, sadece belirli aralıklarla cevap vermeyi seviyorum.

Debounce (1 sn): Merhaba, ben ^^ robotun kuzeniyim. Bana ping atmaya devam ettiğiniz sürece, sessiz kalacağım çünkü son ping yaptığınızdan bu yana sadece 1 saniye geçtikten sonra cevap vermeyi seviyorum . Bilmiyorum, bunun sebebi bir tutum sorunum olması ya da sadece insanları kesmek istememem. Diğer bir deyişle, son çağrınızdan bu yana 1 saniye geçmeden yanıtlarımı sormaya devam ederseniz asla bir yanıt alamazsınız. Evet evet ... devam et! bana kaba de.


Gaz kelebeği (10 dk): Ben bir tomrukçuluk makinesiyim. 10 günlük düzenli aralıklarla sistem günlüklerini arka uç sunucumuza gönderiyorum.

Debounce (10 sec): Merhaba, ben o tomruk makinesinin kuzeni değilim. (Her debouncer , bu hayali dünyada bir gaz kelebeği ile ilişkili değildir ). Yakındaki bir restoranda garson olarak çalışıyorum. Siparişinize bir şeyler eklemeye devam ettiğiniz sürece, siparişinizi yerine getirmek için mutfağa gitmeyeceğimi bilmeliyim. Siparişinizi en son değiştirdikten sonra yalnızca 10 saniye geçtikten sonra siparişinizi tamamladığınızı varsayacağım. Ancak o zaman siparişinizi mutfakta yapacağım.


Harika Demolar: https://css-tricks.com/debouncing-throttling- açıkladı-örnekler/

Garson benzetmesi için krediler: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf


1
en iyi açıklama.
Karan Sharma

17

Sökme , bir işlevin alabileceği çağrıların sıklığını yönetmenizi sağlar. Belirli bir işlevde gerçekleşen birden çok çağrıyı birleştirir, böylece belirli bir süre sona ermeden önce tekrarlanan çağrılar yok sayılır. Temel olarak, birkaç kez gerçekleşebilecek bir olay için tam olarak bir sinyalin gönderilmesini sağlar.

Kısma , bir işlevin sabit bir zaman aralığına aldığı çağrıların sıklığını kısıtlar. Hedef fonksiyonun belirtilen gecikmeden daha sık başlatılmamasını sağlamak için kullanılır. Kısma, tekrar eden bir olayın hızındaki azalmadır.


17

Basit.

Aynı aynı şeyi yaparlar (hız sınırlaması), gaz çağrılırken, sarılmış fonksiyonunuzu periyodik olarak tetikler ve ayrılma olmaz. Debounce, fonksiyonunuzu en sonunda bir kez çağırmaya çalışır.

Örnek : Kaydırma yapıyorsanız, gaz kaydırdığınızda (her X milisaniyede bir) işlevinizi yavaşça çağıracaktır. Debounce, işlevinizi çağırmak için kaydırma işlemini tamamlayana kadar bekler.


Bu demolarda "özdeş" görünmeyebileceğine dikkat etmek gerekir, çünkü gecikme son olaydan sonra her zaman X milisaniye ateşleyecektir, gaz kelebeğinin son çağrısı daha erken gerçekleşebilir (ve gecikme normal olarak ateşlendiğinde tekrar çağrılması gerekmez) ). oldukça önemsiz, ama demolara bakarsanız bahsetmeye değer.
Ryan Taylor

16

Layman'ın terimleriyle:

Zıplamaölçer çalışan bir işlev önleyecektir ise hala sıkça deniliyor. Ayrılmış bir işlev yalnızca artık çağrılmadığı belirlendikten sonra çalışır ; bu noktada tam olarak bir kez çalışır. Suçlamanın pratik örnekleri:

  • Kullanıcı "yazmayı bıraktıysa" bir metin alanının içeriğini otomatik olarak kaydetme veya doğrulama: işlem, kullanıcının artık yazmadığı (artık tuşlara basmadığı) belirlendikten SONRA, yalnızca bir kez yapılacaktır.

  • Kullanıcıların farelerini dinledikleri yerde günlüğe kaydetme: kullanıcı artık farelerini hareket ettirmiyor, böylece (son) konum günlüğe kaydedilebilir.

Kısma , bir işlevin, arama frekansından bağımsız olarak, yakın zamanda çalıştırılması durumunda çalışmasını engelleyecektir. Kısıtlamanın pratik örnekleri:

  • V-sync uygulamaları kısıtlamaya dayanır: ekran yalnızca son ekran çiziminden itibaren 16 ms geçerse çizilir. Ekran yenileme işlevinin kaç kez çağrıldığına bakılmaksızın, en fazla 16 saniyede bir çalışır.

7

Kişisel olarak hatırlamama yardımcı olan gerçek bir analoji:

  • debounce = bir konuşma . cevap vermeden önce diğer kişinin konuşmayı bitirmesini beklersiniz.
  • gaz = bir bateri biti . yalnızca basit bir 4/4 bateri bitinde notlar çalarsınız.

Kalkış için kullanım örnekleri :

  • Yazıyor. Kullanıcı yazmayı bıraktıktan sonra bir şeyler yapmak istiyorsunuz. Son tuş vuruşundan sonra 1 saniye beklemek mantıklı. Her tuş vuruşu beklemeyi yeniden başlatır.
  • Animasyon. Kullanıcı öğenin üzerine gelmeyi bıraktıktan sonra bir öğeyi küçültmek istersiniz. Kalkışın kullanılmaması imlecin "sıcak" ve "soğuk" bölgeler arasında yanlışlıkla hareket etmesinin sonucu olarak düzensiz bir animasyona neden olabilir.

Gaz kelebeği için kullanım durumları :

  • Kaydırma. Kaydırmaya tepki vermek istiyorsunuz ancak yapılan hesaplama miktarını sınırlandırıyorsunuz, bu nedenle potansiyel gecikmeyi önlemek için her 100ms'de bir şey yapmak yeterlidir.
  • Fare hareketi. Kaydırma ile aynı, ancak fare hareketi için.
  • API çağrıları Belirli UI olaylarında bir API çağrısı başlatmak istiyorsunuz ancak sunucunuzu aşırı yüklememek için yaptığınız API çağrılarının sayısını sınırlamak istiyorsunuz.

4

throtle etrafında sarıcı olan gürültüye yapar filtreleme geçti çağrı için functionise, belli bir süre içinde debounce büyük ardından belirtilen olduğu zaman aralığına bir işlev çağrısını geciktirir throtle .



2

kısma

Kısma, bir fonksiyonun fazla mesai olarak adlandırılabileceği en fazla sayıyı zorlar. "Bu işlevi en fazla 100 milisaniyede bir kez gerçekleştirin." Normal şartlar altında bu işlevi 10 saniyede 1.000 kez diyeceğinizi söyleyin. Eğer 100 milisaniyede bir kez gevşetirseniz, bu fonksiyonu en fazla 100 kez uygular

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

zıplamaölçer

Sökme, bir işlevin, çağrılmadan belirli bir süre geçene kadar yeniden çağrılmamasını zorunlu kılar. "Bu işlevi yalnızca 100 milisaniye çağrılmadan geçtiyse" yürütün.

Belki bir fonksiyon hızlı bir patlamada 1.000 kez çağrılır, 3 saniyeye yayılır, sonra çağrılmayı durdurur. 100 milisaniyede kapattıysanız, patlama bittikten sonra işlev yalnızca bir kez, 3.1 saniyede patlar. Patlama sırasında fonksiyon her çağrıldığında, kalkış zamanlayıcısını sıfırlar

Kaynak: - kısma ve açılma


2

"E" olayında çağrılacak bir "cb" geri çağırma fonksiyonumuz olduğunu varsayalım. "E" nin 1 saniyede 1000 kez tetiklenmesine izin verin, dolayısıyla "cb" ye 1000 çağrı olur. Bu 1 çağrı / ms. Optimize etmek için aşağıdakilerden birini kullanabiliriz:

  • Kısma : (100 ms) kısma ile, [c. Bu 1 çağrı / 100 ms'dir. Burada 10 çağrı için optimize edilmiş "cb" için 1000 çağrı.
  • Zıplamaönler (100 ms) bir zıplamaönler ile, "CB" [1100 sn] sadece bir kez olarak isimlendirilirler. Bu, 1000 ms'de gerçekleşen son "E" tetikleyicisinden 100 ms sonra. Burada 1 çağrı için optimize edilmiş "cb" için 1000 çağrı.

1

Anladığım kadarıyla, basit bir şekilde Kısma - belirli sayıda kez çağırmak benzer setInterval (geri arama) yani olay ve zaman meydana geldiği zaman içinde belirli sayıda defa aynı işlevi çağırmak .. Sökme - setTImeout (callbackForApi) çağrısına benzer veya olay gerçekleştiğinde belirli bir süre geçtikten sonra bir işlevi çağırmak. Bu bağlantı yardımcı olabilir- https://css-tricks.com/the-difference-between-throttling-and-debouncing/


0

Sökme işlevi, bir işlevin yalnızca son çağrıldığından beri belirli bir süre sonra çalıştırılabilmesini sağlar

function debounce(func,wait){
  let timeout
  return(...arg) =>{
    clearTimeout(timeout);
    timeout= setTimeout(()=>func.apply(this,arg),wait)
  }
}


function SayHello(){
  console.log("Jesus is saying hello!!")
}


let x = debounce(SayHello,3000)
x()

Gaz kelebeği kalıbı, belli bir olay işleyicisi zamanla çağrılabilir maksimum tekrar sayısını sınırlar. Bu bekleme süresi sona ermeden önce yapılan her çağrıyı yok sayarak, işleyicinin belirli aralıklarla periyodik olarak çağrılmasını sağlar.

function throttle(callback, interval) {
  let enableCall = true;

  return (...args)=> {
    if (!enableCall) return;

    enableCall = false;
    callback.apply(this, args);
    setTimeout(() => enableCall = true, interval);
  }
}


function helloFromThrottle(){
  console.log("Jesus is saying hi!!!")
}

const foo = throttle(helloFromThrottle,5000)
foo()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.