zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    真机分享文件到虚拟机的centos 7 分享文件位置记录
    Linux系统列出某个用户组里的所有用户命令
    笔记之Linux命令vi
    笔记之Linux系统文件管理命令
    我的C#
    消息框
    ddt数据驱动在ui自动化中的应用二【多测师】
    ddt数据驱动在ui自动化中的应用一【多测师】
    基于ddt+unittest+Excel做接口测试自动化测试【多测师】
    Python操作MD5加密【多测师】
  • 原文地址:https://www.cnblogs.com/weboey/p/7815628.html
Copyright © 2011-2022 走看看