2014-05-06 28 views
6

Belirli davranışları değiştirebileceğinden bir onay kutum var, ancak birisi ardışık 100 tıklama yaptığında, sunucu tarafıma 100 istek göndermek istemiyorum. Sonraajax istekleri doğru şekilde nasıl çözülür

deBouncer(jQuery,'smartoggle', 'click', 1500); 

olayın kendisi:

$(window).smartoggle(function(e){ 
    MyToggleFunction(); 
}); 
benim belge hazır fonksiyonunda

deBouncer = function($,cf,of, interval){ 
    var debounce = function (func, threshold, execAsap) { 
     var timeout; 
     return function debounced() { 
      var obj = this, args = arguments; 
      function delayed() { 
      if (!execAsap) 
       func.apply(obj, args); 
      timeout = null; 
      } 
      if (timeout) 
      clearTimeout(timeout); 
      else if (execAsap) 
      func.apply(obj, args); 
      timeout = setTimeout(delayed, threshold || interval); 
     } 
    } 
    jQuery.fn[cf] = function(fn){ return fn ? this.bind(of, debounce(fn)) : this.trigger(cf); }; 
    }; 

:

Bu

I (bu kod parçacığı bulundu) şimdiye kadar yerinde ne var

Bu, 1500 ms ayırma periyodu olarak 1500 ms koyduğum gibi çalışır, bu yüzden 1500 ms'lik bir zamana tıklarsanız, yalnızca t O sunucuya son durumu.

Bunu kullanmanın yan etkisi var, artık diğer şeyler için tıklama etkinliğim berbat. Burada yanlış bir şey mi yapıyorum? Geri çekilmenin daha iyi bir yolu var mı?

+0

Kesinlikle buradaki yazma yolundasınız .. Bu olayı yalnızca söz konusu onay işaretine bağladım. Bu, diğer kodların bazılarını basitleştirmenize izin verebilir. –

+0

@JeremyJStarcher, ne demek istediğin hakkında bir örnek verebilir misin? –

+0

İşaretlemenizi görmem gerekiyor ... ya da size nasıl yaptığımı temel alan bir örnek verebilirim. –

cevap

2

Bunu yapmak için "uygun" bir yol olup olmadığından emin değilsiniz.

var MyToggleDebounced = _.debounce(MyToggleFunction, 1500); 

sonra tıklatma işleyicisi MyToggleDebounced kullanmak ... çizgi senin fonksiyonunun bir debounced sürümünü oluşturur böyle bir fayda taşıdığını söyledi.

Link to debounce docs on underscorejs

yaptıklarını nasıl açıklamalı kaynağında bir göz atın.

8

Sadece gerçek işi yapan işlevi ayıklayın ve bunun için tüm kitaplığı yüklemedim.

var debouncedSomeFunction = debounce(someFunction, 1500); 
 

 
debouncedSomeFunction(); 
 
debouncedSomeFunction(); 
 
debouncedSomeFunction(); 
 

 
setTimeout(debouncedSomeFunction, 2000); 
 

 

 
function debounce(fn, bufferInterval) { 
 
    var timeout; 
 

 
    return function() { 
 
    clearTimeout(timeout); 
 
    timeout = setTimeout(fn.apply.bind(fn, this, arguments), bufferInterval); 
 
    }; 
 

 
} 
 

 
function someFunction() { 
 
    log('someFunction executed'); 
 
} 
 

 
function log(text) { 
 
    document.body.appendChild(document.createTextNode(text)); 
 
    document.body.appendChild(document.createElement('br')); 
 
}

+0

Bunun sahte kod olduğunu biliyorum, ancak son satırın kendi kendini referansla ne ifade ettiği konusunda kafam karışmış durumda. Belki de cevabınızı * YourFunction * uygulamasının basit bir uygulamasını göstererek güncelleştirebilirsiniz. Bu kodu denedim ve işe yaramayacaktım. – geoidesic

+0

Sadece açıklık için, bir başkasının son satır tarafından karışması durumunda ... olmalı * var yourFunction = function() {}; yourFunction = geri dönme (isminiz, 1500); – geoidesic

+0

@geoidesic Kodu değiştirdim, umarım bu daha kolay anlaşılır. – plalx

0

bu soru başlangıçta göründüğünden daha iyi olduğunu düşünüyorum. Http Ajax'ın nasıl çalıştığı konusunda bir uyarı var. Gecikmeyi 1500 ms olarak ayarlarsanız ve her isteğin bu süre zarfında sunulduğunu garanti ederseniz diğer cevaplar işe yarayacaktır. Bununla birlikte, herhangi bir talep önemli ölçüde yavaşlarsa, talepler düzensiz olabilir. Böyle bir durumda, son işlenen istek, son gönderilen değil, verilerin gösterileceği istektir.

ben bu uyarı önlemek için bu sınıf yazdım (daktilo, ama bunu okumak mümkün olmalıdır):

export class AjaxSync { 

    private isLoading: boolean = false; 
    private pendingCallback: Function; 
    private timeout; 

    public debounce(time: number, callback: Function): Function { 
    return this.wrapInTimeout(
     time, 
    () => { 
     if (this.isLoading) { 
      this.pendingCallback = callback; 
      return; 
     } 
     this.isLoading = true; 
     callback() 
      .then(() => { 
      this.isLoading = false; 
      if (this.pendingCallback) { 
       const pendingCallback = this.pendingCallback; 
       this.pendingCallback = null; 
       this.debounce(time, pendingCallback); 
      } 
      }); 
     } 
    ); 
    } 

    private wrapInTimeout(time, callback) { 
    return() => { 
     clearTimeout(this.timeout); 
     this.timeout = setTimeout(callback, time); 
    }; 
    } 
} 

Bu aynı zamanda işlenmiş iki ajax-istekleri engeller ve bu başka gönderecek Bekleyen bir istek varsa iste.

İlgili konular