• JS 函数节流和防抖 Better


    目的

    函数防抖和函数节流:优化高频率执行js代码的一种手段,js中的一些事件如浏览器的resize、scroll,鼠标的mousemove、mouseover,input输入框的keypress等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能。为了优化体验,需要对这类事件进行调用次数的限制。
    简而言之,目的都是,降低回调执行频率。节省计算资源。

    函数防抖

    高频事件触发,n秒后只执行一次,如果n秒内再次被触发,则重新计算时间。

    实现代码

    // ES6 可立即执行版本(封装完成未测试,应该好用)
    /**
     * @param {fn} 
     * @param {delay} 时间间隔ms
     * @param {isRun}  是否立即执行:true false
     * @return {*}
     */
    function debounce(fn, delay=100, isRun=false){
      let timer = null;
      return function(){
        let args = arguments;
        if(timer){
          clearTimeout(timer)
        }else{
          isRun && fn.apply(this, args)
        }
        timer = setTimeout(()=>{
          timer = null;
          fn.apply(this, args)
        }, delay)
      }
    }
    
    // ES5  延时执行 版本
    function debounce(fn, delay) {
        var timer; // 维护一个 timer
        return function () {
            var _this = this; // 取debounce执行作用域的this
            var args = arguments;
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(function () {
                fn.apply(_this, args); // 用apply指向调用debounce的对象,相当于_this.fn(args);
            }, delay);
        };
    }
    
    // ES6 延时执行 版本
    function debounce (fn, delay=100){
      let timer = null
      return function () {
        if(timer){
          clearTimeout(timer)
        }
        timer = setTimeout(() => {
          fn.apply(this, arguments)
          timer = null
        }, delay);
      }
    }
    

    测试用例

    function testDebounce(e, content) {
        console.log(e, content);
    }
    var testDebounceFn = debounce(testDebounce, 1000); // 防抖函数
    document.onmousemove = function (e) {
        testDebounceFn(e, 'debounce'); // 给防抖函数传参
    }
    

    函数节流

    高频事件触发,n秒内只会执行一次。

    实现代码

    // ES6 可立即执行版本(已测试,好用!!!)
    /**
     * @param {fn} 
     * @param {delay} 时间间隔ms
     * @param {isRun}  是否立即执行:true false
     * @return {*}
     */
    function throttle(fn, delay=100, isRun=true){
      let timer = null;
      return function(){
        let args = arguments;
        if(!timer){
          isRun && fn.apply(this, args)
          timer = setTimeout(()=>{
            timer = null;
            isRun || fn.apply(this, args)
          }, delay)
        }
      }
    }
    
    // ES5 延时执行 版本
    function throttle(fn, delay) {
        var timer;
        return function () {
            var _this = this;
            var args = arguments;
            if (timer) {
                return;
            }
            timer = setTimeout(function () {
                fn.apply(_this, args);
                timer = null; // 在delay后执行完fn之后清空timer,此时timer为假,throttle触发可以进入计时器
            }, delay)
        }
    }
    
    // ES6 延时执行 版本(已测试,好用!!!)
    function throttle(fn, delay=100){
      let timer
      return function() {
        if(timer) {
          return
        }
        timer = setTimeout(()=> {
          fn.apply(this, arguments)
          timer = null
        }, delay)
      }
    }
    

    测试用例

    function testThrottle(e, content) {
        console.log(e, content);
    }
    var testThrottleFn = throttle(testThrottle, 1000); // 节流函数
    document.onmousemove = function (e) {
        testThrottleFn(e, 'throttle'); // 给节流函数传参
    }
    

    补充:工具函数在Vue中的使用

    methods: {
        handleSearch(value) {...},
        debounceHandleSearch: debounce(function(){this.handleSearch(...arguments)}, 1000),
    	// 因为在运行阶段,debounce函数中 `this` 的指向不是Vue实例,因此获取不到 `handleSearch`,所以在编写阶段“待执行函数”用一层函数包装后,立即执行,从而敲定该函数的运行环境。
    }
    

    常见应用场景

    函数防抖的应用场景

    • 搜索框搜索输入。只需用户最后一次输入完,再发送请求。
    • 手机号、邮箱验证输入检测。
    • 窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

    函数节流的应用场景

    • 滚动加载,加载更多或滚到底部监听
    • 拖拽一个元素,要随时获取被拖拽元素的位置
    • 高频点击提交,表单重复提交

    参考:[https://segmentfault.com/a/1190000018445196]

  • 相关阅读:
    一个开始搞Linux的现任前端开发,用U盘装CentOS
    .NET:处理数据库事务中的并发
    Xml与对象之间的序列化、反序列化
    嵌套类
    .NET陷阱之五:奇怪的OutOfMemoryException——大对象堆引起的问题与对策
    backbone 之事件(events)
    一道笔试指针题目详解
    linux安装Cassandra数据库
    Angularjs Controller 间通信机制
    NLucene 和 Lucene .NET
  • 原文地址:https://www.cnblogs.com/huangtq/p/14498353.html
Copyright © 2020-2023  润新知