JS函数节流防抖

来源:互联网 发布:怎样快速提升淘宝信誉 编辑:程序博客网 时间:2024/04/30 09:54

在前端开发中有一部分的用户行为会频繁的触发事件执行,而对于DOM操作、资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器的崩溃。函数节流(throttle)和函数防抖(debounce)就是为了解决类似需求应运而生的。
节流防抖

原文链接

函数节流(throttle)

函数节流就是预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。好像水滴攒到一定重量才会落下一样。

场景:
* 窗口调整(resize)
* 页面滚动(scroll)
* 抢购疯狂点击(mousedown)

实现:

function throttle(method, delay){    var last = 0;    return function (){        var now = +new Date();        if(now - last > delay){            method.apply(this,arguments);            last = now;        }    }}document.getElementById('throttle').onclick = throttle(function(){console.log('click')},2000);

underscore实现:

_.throttle = function(func, wait, options) {    var context, args, result;    var timeout = null;    var previous = 0;    if (!options) options = {};    var later = function() {        previous = options.leading === false ? 0 : _.now();        timeout = null;        result = func.apply(context, args);        if (!timeout) context = args = null;    };    return function() {        var now = _.now();        if (!previous && options.leading === false) previous = now;        //计算剩余时间        var remaining = wait - (now - previous);        context = this;        args = arguments;        //剩余时间小于等于0或者剩余时间大于等待时间(本地时间变动出现)        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;    };};    

函数防抖(debounce)

函数防抖就是在函数需要频繁触发情况时,只有足够空闲的时间,才执行一次。好像公交司机会等人都上车后才出站一样。

场景:
* 实时搜索(keyup)
* 拖拽(mousemove)

实现:

function debounce(method, delay){    var timer = null;    return function(){        var context = this,args = arguments;        clearTimeout(timer);        timer = setTimeout(function(){            method.apply(context, args);        },delay);    }}document.getElementById('debounce').onclick = debounce(function(){console.log('click')},2000);

underscore实现:

_.debounce = function(func, wait, immediate) {    var timeout, args, context, timestamp, result;    var later = function() {        var last = _.now() - timestamp;        if (last < wait && last >= 0) {            timeout = setTimeout(later, wait - last);        } else {            timeout = null;            if (!immediate) {                result = func.apply(context, args);                if (!timeout) context = args = null;            }        }    };    return function() {        context = this;        args = arguments;        timestamp = _.now();        var callNow = immediate && !timeout;        if (!timeout) timeout = setTimeout(later, wait);        if (callNow) {            result = func.apply(context, args);            context = args = null;        }        return result;    };};    

函数节流(throttle)和函数防抖(debounce)都是通过延时逻辑操作来提升性能的方法,在前端优化中是常见且重要的解决方式。可以从概念和实际应用中理解两者的区别,在需要的时候选择合适的方法处理。