JS函数节流代码实现

函数被频繁调用场景

Js中的函数大多数情况下都是由用户主动调用触发的,一般不会遇到性能相关的问题。但在一些少数情况下,函数的触发不是由用户直接控制。在这些场景下,函数有可能被非常频繁地调用,而造成大的性能问题。

比如以下场景:

  1. window.onresize事件。如果我们给window对象绑定了resize事件,当浏览器窗口大小被改变的时候,这个事件的触发的频率非常高。(其实任何元素节点也是可以绑定resize事件的,如何实现可参考 如何给div绑定resize事件。也可以使用第三方库 resize-observer-polyfill)
  2. mousemove事件。
  3. DOM变化观察者MutationObserver。dom的变化造成观察者对象被频繁触发。

函数节流的原理:

函数节流的原理就是使用定时器来控制函数调用。当触发一个事件函数时,先setTimout让这个事件延迟一会再执行,如果在这个时间间隔内又触发了事件,那我们就clear掉原来的定时器,再setTimeout一个新的定时器延迟一会执行。

代码实现

var throttle=function(fn,interval){
    var _self=fn; //保存需要被延长执行的函数引用
    var timer;
    var firstTime=true;   //是否是第一次调用

    return function (){
        var args=arguments;
        var _this=this;
        if(firstTime){  //如果第一次调用,不需要延迟执行
            _self.apply(_this,args);
            return firstTime = false;
        }
        if(timer){  //如果定时器还在,说明前一次延迟执行还没有完成
            return false;
        }
        timer = setTimeout(function(){  //延迟一段时间执行
            clearTimeout(timer);
            timer=null;
            _self.apply(_this,args);
        },interval || 500);
    };
};
View Code 方式1
var throttle2 = function (callback, delay, trailingTimeout) {
    var leadingCall = false,
        trailingCall = false,
        lastCallTime = 0;

    function resolvePending() {
        if (leadingCall) {
            leadingCall = false;
            callback();
        }
        if (trailingCall) {
            proxy();
        }
    }

    function timeoutCallback() {
        requestAnimationFrame(resolvePending);
    }

    function proxy() {
        var timeStamp = Date.now();
        if (leadingCall) {
            if (timeStamp - lastCallTime < trailingTimeout) {
                return;
            }
            trailingCall = true;
        } else {
            leadingCall = true;
            trailingCall = false;
            setTimeout(timeoutCallback, delay);
        }
        lastCallTime = timeStamp;
    }
    return proxy;
};
View Code 方式2

代码测试

window.onresize=throttle(function(){
    console.log(1);
},1000);

 

posted @ 2017-11-10 17:23  weboey  阅读(1641)  评论(0编辑  收藏  举报