2016-12-12 51 views
3

David Walshは、デバウンスの実装が偉大であるhereです。引数でデバウンス関数呼び出しを呼び出す

// 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. 
function debounce(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); 
    }; 
}; 

私はそれを生産で使用しており、素晴らしいです。

今、私はデバウンスの必要性のもう少し複雑なケースに遭遇しました。

私は、次のようなパラメータでイベントハンドラを呼び出すイベントがあります。 $(elem).on( 'onSomeEvent'、(e)=> {handler(e.X)});

このイベントが頻繁にトリガされ、ハンドラを1000秒も呼び出すことができます。私はハンドラ自体をデバウンスする必要はありません。 しかし、私の場合は、各e.Xについて、250msというだけで一度だけ呼びたいと思っています。

私はxと最後の実行時間を保持する2次元配列を作成することを考えていましたが、グローバル変数を宣言したくありません。

アイデア?

export function debounceWithId(func, wait, id, immediate?) { 
     var timeouts = {}; 
     return function() { 
      var context = this, args = arguments; 
      var later = function() { 
       timeouts[id] = null; 
       if (!immediate) func.apply(context, args); 
      }; 
      var callNow = immediate && !timeouts[id]; 
      clearTimeout(timeouts[id]); 
      timeouts[id] = setTimeout(later, wait); 
      if (callNow) func.apply(context, args); 
     }; 
    }; 
+0

'var timeout'も元のコードのグローバル変数ではありませんか? – Bergi

+0

残念ながら、 – Dorad

+0

と思われます。残念ながら、あなたが望むものはありませんか? – Bergi

答えて

3

私がいつも使用すると、次のされています:

var debounce = (function() { 
    var timers = {}; 

    return function (callback, delay, id) { 
     delay = delay || 500; 
     id = id || "duplicated event"; 

     if (timers[id]) { 
      clearTimeout(timers[id]); 
     } 

     timers[id] = setTimeout(callback, delay); 
    }; 
})(); // note the call here so the call for `func_to_param` is omitted 
私はこのようにそれを実装して、それが働いた@Timベルマーレンの答えを読んだ後

* EDIT *

私はイベントに一意のIDを追加できるという事実を除いて、あなたの解決策に大きな違いがあるとは思わない。私が正しく理解している場合はhandler(e.X)の周りにこれをラップする必要があります。

debounce(func_to_param, 250, 'mousewheel'); 
debounce(func_to_param, 250, 'scrolling'); 
+1

私は今しようとしているとあなたに知らせるでしょう。 – Dorad

+1

チャームのように働いた。私は他人のために私の変更を掲載しています。 – Dorad

関連する問題