函数节流

讲真 哪一个是节流throttle,哪一个是去抖debounce,无所谓啦。。。javascript

硬要区分的话,我以为是这种:css

http://blog.peterwf.com/2015/11/17/debounce-throttle/前端

参考:https://css-tricks.com/the-difference-between-throttling-and-debouncing/java

 

或者就不要区分了,就都是节流。这个讲得最好:sublime-text

http://www.alloyteam.com/2012/11/javascript-throttle/#prettyPhoto浏览器

 function throttle(fn,delay){
        var timer = null;
        console.log(this);//window
        return function (){//使用闭包,保证了全局的timer
            var context = this, args = arguments;
//            console.log(this);//btn
            clearTimeout(timer);
            timer = setTimeout(function (){
                fn.apply(context,args);//context保证了fn里的this的正确性:btn
            },delay);
        };
    };
    function fn(){
        console.log(this);
        console.log("执行");
    }
    $("#btn").on("click",throttle(fn, 1000));
    //click以前就执行了throttle。执行结果给了click
//    $("#btn").on("click",fn);

什么是函数节流?

介绍前,先说下背景。在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特色,就是用户没必要特意捣乱,他在一个正常的操做中,都有可能在一个短的时间内触发很是屡次事件绑定程序。而你们知道,DOM操做时很消耗性能的,这个时候,若是你为这些事件绑定一些操做DOM节点的操做的话,那就会引起大量的计算,在用户看来,页面可能就一时间没有响应,这个页面一会儿变卡了变慢了。甚至在IE下,若是你绑定的resize事件进行较多DOM操做,其高频率可能直接就使得浏览器崩溃。闭包

怎么解决?函数节流就是一种办法。话说第一次接触函数节流(throttle),仍是在看impress源代码的时候,impress在播放的时候,若是窗口大小发生改变(resize),它会对总体进行缩放(scale),使得每一帧都完整显示在屏幕上:app

impress在resize的时候自动适应

稍微留心,你会发现,当你改变窗体大小的时候,无论你怎么拉,怎么拽,都没有马上生效,而是在你改变完大小后的一下子,它的内容才进行缩放适应。看了源代码,它用的就是函数节流的方法。ide

函数节流,简单地讲,就是让一个函数没法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用。以impress上面的例子讲,就是让缩放内容的操做在你不断改变窗口大小的时候不会执行,只有你停下来一下子,才会开始执行。函数

 

函数节流的原理

函数节流的原理挺简单的,估计你们都想到了,那就是定时器。当我触发一个时间时,先setTimout让这个事件延迟一会再执行,若是在这个时间间隔内又触发了事件,那咱们就clear掉原来的定时器,再setTimeout一个新的定时器延迟一会执行,就这样。

代码实现

明白了原理,那就能够在代码里用上了,但每次都要手动去新建清除定时器毕竟麻烦,因而须要封装。在《JavaScript高级程序设计》一书有介绍函数节流,里面封装了这样一个函数节流函数:

它把定时器ID存为函数的一个属性(= =我的的世界观不喜欢这种写法)。而调用的时候就直接写

这样两次函数调用之间至少间隔100ms。

而impress用的是另外一个封装函数:

它使用闭包的方法造成一个私有的做用域来存放定时器变量timer。而调用方法为

两种方法各有优劣,前一个封装函数的优点在把上下文变量当作函数参数,直接能够定制执行函数的this变量;后一个函数优点在于把延迟时间当作变量(固然,前一个函数很容易作这个拓展),并且我的以为使用闭包代码结构会更优,且易于拓展定制其余私有变量,缺点就是虽然使用apply把调用throttle时的this上下文传给执行函数,但毕竟不够灵活。

接下来是?

接下来就讨论怎么更好地封装?这多没意思啊,接下来讨论下怎样拓展深化函数节流。

真是棒!

http://www.alloyteam.com/2012/11/javascript-throttle/#prettyPhoto

相关文章
相关标签/搜索