跳转至

Debounce vs Throttle

DebounceThrottle是javascript中两种手段来控制函数的执行,特别是事件的处理。

当处理scroll,resize, keyup等事件时候,由于每秒触发的时间频次太多,不断的通过绑定回调函数来处理,会对浏览器造成巨大压力。这时候Debounce和Throttle就派上用场了。

Debounce

debounce强制函数某段时间只会执行一次,会把大量事件聚合在一次执行,哪怕它本来会被调用多次。

而throttle好比每隔15分钟一趟的电梯,过点不侯,debounce也每隔15分钟一趟,但当它看见有人要进来时候,它会允许进来,并从进来那一刻算起在等15分钟,如果15分钟内没有人进来了,就会开走。

下面两个场景适用debounce: 1. 当用户设置浏览器宽度,页面重新布局时候 2. 当用户输入内容,向服务器发起ajax查询,返回搜索建议时候。通过监听用户keyup事件,当停止输入时候,发起ajax查询

debounce一个简单实现:

function debounce (fn, delay) {
    var timer;
    return function () {
        var context = this,
            args = arguments; 
        clearTimeout(timer);
        timer = setTimeout(function () {
                fn.apply(context, args);
        }, delay);
    }
}

如果debounce的电梯一直有人来,那么就会值等待下去,如果我们想超过一定时间就要开走,可以加个最大等待时间来处理,实现如下:

function debounce (fn, delay, maxWait) {
    var timeout, first, args, context, 
        later = function() {
            fn.apply(context, args);
            timeout = first = args = context = null;
        };
    return function() {
        context = this;
        args = arguments;
        if (!first) {
            first = Date.now();
        }

        clearTimeout(timeout);

        if (maxWait < (Date.now() - first)) {
            later();
        } else {
            timeout = setTimeout(later, delay);
        }
    };
}

Throttle

throttle会以固定的频率执行函数,好比水龙头固定速率流水。

throttle适用一定频率执行回调的场景。比如瀑布流,如果采用debounce方式,那么只有用户停止滚动屏幕时候才加载更多内容,这非常不友好。这时候可以固定频率来判断用户是否到屏幕底部,然后加载更多内容

throttle一个简单实现:

function throttle(fn, threshhold) {
    var last, timer;
    threshhold || (threshhold = 250);

    return function () {
        var context = this,
            args = arguments,
            now = +new Date();
        //如果距离上次执行fn函数的时间小于threshhold,那么就放弃执行fn,并重新计时
        if (last && now < last + threshhold) {
            clearTimeout(timer)
            timer = setTimeout(function () {
                last = fn.apply(context, args);
            }, threshhold)
        } else {
            last = now;
            fn.apply(context, args);
        }
    }
}

参考

debounce与throttle区别 Debounce 和 Throttle 的原理及实现 Debouncing and Throttling Explained Through Examples

评论