javascriptのdebounce関数

3638 ワード

イベントバインディング関数の後に、イベントが連続的に発生すると、バインディング関数がトリガーに連絡するという問題があります.しかし、関数を連続的に出発させて実行したくないです.最後のイベントが現れたら、一回のバインディング関数をトリガしたいだけです.一場面例によれば、keydownイベントは、ユーザがキーを押し続けて放さないと、バインディングの関数が継続的に実行をトリガする.ユーザー体験が悪い.この時はdebounce関数が役に立ちます.まずdebounce関数のプロトタイプを見てください.
debounce(function、wait、immediate)debounce関数の大まかな考えは、延長時間を指定するユーザの関数に戻ります.この関数が繰り返し起動されると、関数は実行されず、再び延長を開始し、遅延時間だけ終了します.この関数は実行されます.undersscore.jsとlodash.jsのような有名なjavascriptライブラリは全部debounceを提供しました.
自分で書いてみました.
function debounce(func, delay) {
    var timeout;
    return function () {
        if (timeout) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(function() {
            func();
        }, delay);
    }
}

var log = function() {
    console.log('haha');
}
var dlog = debounce(log, 1000);
dlog();
dlog();
dlog();
dlog(); //           ‘haha'
以下は[ここ]を参考にして、改善版を書きます.
// 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);
    };
};

// Usage
var myEfficientFn = debounce(function() {
    // All the taxing stuff you do
}, 250);
window.addEventListener('resize', myEfficientFn);