JS函数节流(throttle)与函数去抖(debounce)

JS函数节流(throttle)与函数去抖(debounce)

2017-11-15 / 0 评论 / 136 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年10月27日,已超过1121天没有更新,若内容或图片失效,请留言反馈。

在浏览器中,往往由于事件频繁被触发,因而频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃。相关事件如 resize , scroll , mousemove 等。在实际场景中,需求大多为停止改变大小n毫秒后执行后续处理或者是以一定的频率执行后续处理。针对这两种需求就出现了 debouncethrottle 两种解决办法。

throttle 节流

如果将水龙头拧紧直到水是以水滴的形式流出,那你会发现每隔一段时间,就会有一滴水流出。

也就是会说预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。

实现代码

function(func, wait, options) {
        var timeout, context, args, result;
        var previous = 0;
        if (!options) options = {};
        var later = function() {
            previous = options.leading === false ? 0 : new Date().getTime();
            timeout = null;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        };
        var throttled = function() {
            var now = new Date().getTime();
            if (!previous && options.leading === false) previous = now;
            var remaining = wait - (now - previous);
            context = this;
            args = arguments;
            if (remaining <= 0 || remaining > wait) {
                if (timeout) {
                    clearTimeout(timeout);
                    timeout = null;
                }
                previous = now;
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            } else if (!timeout && options.trailing !== false) {
                timeout = setTimeout(later, remaining);
            }
            return result;
        };
        throttled.cancel = function() {
            clearTimeout(timeout);
            previous = 0;
            timeout = context = args = null;
        };
        return throttled;
    }

使用代码

tag.onmousemoveApplet = app.throttle(function() {
  console.log('1s内响应一次!');
        }, 1000);

debounce 去抖

如果用手指一直按住一个弹簧,它将不会弹起直到你松手为止。

也就是说当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。

实现代码

function(func, wait, immediate) {
        var timeout, result;
        var later = function(context, args) {
            timeout = null;
            if (args) result = func.apply(context, args);
        };
        var debounced = restArgs(function(args) {
            if (timeout) clearTimeout(timeout);
            if (immediate) {
                var callNow = !timeout;
                timeout = setTimeout(later, wait);
                if (callNow) result = func.apply(this, args);
            } else {
                timeout = _.delay(later, wait, this, args);
            }
            return result;
        });
        debounced.cancel = function() {
            clearTimeout(timeout);
            timeout = null;
        };
        return debounced;
    }

使用代码

tag.onmousemoveApplet = app.throttle(function() {
  console.log('停下1s后响应一次!');
        }, 1000);

0

评论 (0)

取消