zoukankan      html  css  js  c++  java
  • 函数节流与函数防抖

    函数节流(throttle)

    函数节流:在指定的间隔时间内只执行一次

    有个需要频繁触发函数,出于优化性能角度,在规定时间内,只让函数触发的第一次生效,后面不生效。

    比如下面的例子,在不加函数节流的时候,每当滚动条滚动的时候都会触发一次,造成大量的性能浪费

    // 未添加节流函数
    document.onscroll = function () {
      console.log('scroll事件被触发了')
    }
    

    添加了节流函数后

    // 添加了节流函数
    document.onscroll = throttle(function () {
      console.log('scroll事件被触发了')
    }, 300)
    

    具体代码实现

    /**
     * @description 函数节流
     * @param {Function} fn 需要执行函数节流的函数
     * @param {Number} interval 指定间隔时间
     */
    function throttle(fn, interval = 300) {
      let canRun = true // 通过闭包保存一个标记
      return function () {
        if (!canRun) return // 第一次调用执行
        canRun = false // setTimeout未执行时,后续fn函数调用都不会再执行
        // setTimeout 定时器延时执行
        setTimeout(() => {
          fn.apply(this, arguments)
          canRun = true // 标记为true,节流完成
        }, interval)
      }
    }
    

    代码解释

    原理:将即将被执行的函数用setTimout延迟一段时间执行,如果该次延迟执行还没有完成,则忽略接下来调用该函数的请求。

    简单来说,函数的节流就是通过闭包保存一个标记(canRun = true), 在函数的开头判断这个标记是否为true,如果这个标记为true的话就继续执行,否则就return掉,判断完标记后立即把这个标记设置为false,然后把外部传入的函数的执行包在一个setTimout中,最后在定时器执行完毕之后再把标记设置为true,表示本次延迟执行完毕,可以执行下一次循环了。当定时器还未执行完毕的时候,canRun这个标记始终未false,故在开头的判断中总是被return掉,函数并未执行

    应用场景

    监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次等

    函数防抖(debounce)

    函数防抖: 一个需要频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效。

    比如点击一个按钮,每点击一次就会触发一次事件,在没有加防抖函数的情况下,快速点击会导致多次触发

    // 未加防抖函数
    document.getElementById('btn').onclick = function(){
      console.log('我被点击了');
    }
    

    在加了防抖函数后,只会在规定时间后触发一次

    // 加了防抖函数
    document.getElementById('btn').onclick = debounce(function(){
      console.log('我被点击了');
    },300)
    

    具体代码实现

    /**
     * @description 函数防抖
     * @param {Function} fn 需要执行函数防抖的函数
     * @param {Number} interval 指定间隔时间
     */
    function debounce(fn, interval = 300) {
      let timeout = null // 通过闭包保存一个标记
      return function () {
        clearTimeout(timeout) // 把前一个定时器去掉
        // 又创建一个新的定时器
        timeout = setTimeout(() => {
          fn.apply(this, arguments) // 指定的时间间隔之后运行fn
        }, interval)
      }
    }
    

    代码解释

    其原理就第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器,然后延迟一定时间再执行。

    应用场景

    文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)

  • 相关阅读:
    Delphi 农历算法
    Installing Custom Maps for L4D
    双网卡,上网走外网网卡,内网走内网网卡设置
    L4D的指令合集
    两个RGB的颜色半透明混色算法
    中国省级行政区划变动情况
    Win7编程:在按钮中加入管理员权限运行
    教你快速识别手机质量的好坏
    如何利用预编译指令来判断Delphi 的版本?
    在.NET中读写INI文件 ——兼谈正则表达式的应用
  • 原文地址:https://www.cnblogs.com/cqkjxxxx/p/13358083.html
Copyright © 2011-2022 走看看