zoukankan      html  css  js  c++  java
  • 函数节流(throttle)与函数去抖(debounce)

    一、 引申

      在项目中总会碰到一些因为事件频繁触发,导致 DOM 操作、资源加载等严重消耗资源行为。

      1. window对象的resize、scroll事件

      2. 拖拽时的mousemove事件

      3. 射击游戏中的mousedown、keydown事件

      4. 文字输入、自动完成的keyup事件

      针对这些事件就出现了debounce和throttle两种解决办法。

    二、函数节流(throttle)

    规定在一个时间间隔内,只能触发一次函数。即使这个时间间隔内触发多次函数,也只有一次生效。

    throttle (fn, interval){
      let last = 0
      return function() {
        let cur = Date.now()
        if (cur - last > interval) {
          fn.apply(this, arguments)
          last = cur
        }
      }
    }

     三、 函数去抖(debounce)

    // 思路:在规定时间内未触发第二次,则执行,即在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

    在《JavaScript高级程序设计》一书有介绍函数去抖,里面封装了这样一个函数去抖函数:

    function throttle(method, context) {
         clearTimeout(methor.tId);
         method.tId = setTimeout(function(){
             method.call(context);
         }, 1000);
     }

    它把定时器ID存为函数的一个属性。并且没有触发1s调用一次,而调用的时候就直接写

    window.onresize = function(){
        throttle(myFunc);
    }

    它就是利用为函数添加属性的方式增加定时器,但是可能会被修改,下面是我自己封装的一个使用闭包的去抖函数。高内聚低耦合

     function debounce (fn, delay) {
      let lastFn = null
     // 利用闭包保存定时器 return function() { let args = arguments
      // 在规定时间内再次出发会先清除定时器后再重设定时器 clearTimeout(lastFunc) lastFn = setTimeout(() => { fn.apply(this, args) }, delay) } }
    function fn () {
      console.log('防抖')
    }

    let debounceFn = debounce(fn, 1000) // 重要,需要将去抖函数指向内存中闭包位置

    某DOM.addEventListener('scroll', function () { // 也可以改为其他任意方法
      debounceFn()
    }) 

     

    总结

    • 函数去抖和函数节流都是防止某一时间频繁触发,但是这两兄弟之间的原理却不一样。
    • 函数去抖是某一段时间内只执行一次,而函数节流是间隔时间执行。
  • 相关阅读:
    RxJava API使用示例
    使用create-react-app模板模仿12306app
    web 基本概念辨异 —— URI 与 URL
    RESTful 架构与 RESTful 服务
    python startswith和endswith
    python enumerate函数用法
    python中PIL.Image和OpenCV图像格式相互转换
    Linux查看当前在线用户信息
    Linux查看GPU信息和使用情况
    python中的编码和解码
  • 原文地址:https://www.cnblogs.com/chase-star/p/11300930.html
Copyright © 2011-2022 走看看