JavaScript高级——函数防抖与函数节流

函数防抖和函数节流是两个目的一样的方法,主要用于向服务器发送请求时的优化,防止发送请求的频率过高。不同之处在于,函数防抖是每n秒结束调用一次,函数节流是每n秒内调用一次。

函数防抖 Debounce

概念:在函数被触发n秒后再调用,如果n秒内再次触发,则重新计时。限定在一定时间内函数只能执行一次(防止你手抖点多次),而且执行的是在这一定时间内最后一次调用。
函数去抖就是对于一定时间段的连续的函数调用,只让其执行一次。

function success(){
    console.log("提交成功")
}
// 1 定义防抖函数
const debounce = (fn, delay) => {
    let timer = null
    // 4 把setTimeout函数的结果返回给debounce函数
    return (...args) =>{  //省略号表明输入不定参数,所有传递进来的参数都被放到一个数组中,赋值给变量args
        // 5 清除前上一次delay时间内触发的函数,确保最后一次触发重新计时调用
        clearTimeout(timer)
        // 3 设置一个定时器
        timer = setTimeout(()=>{ // 注意这里要设置一个匿名函数调用fn()不能直接调用
            fn.apply(this, args)},delay)   // 用apply绑定debounce对象this,arguments用于传参
    }
}

// 2 调用防抖函数
const Ondebounce = debounce(success, 2000) 

let btn = document.getElementById("btn")
btn.addEventListener("click", Ondebounce)

函数节流 Throttle

概念:在一个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
函数节流的核心是,让一个函数不要执行得太频繁,减少一些过快的调用来节流。类似于建一个水坝让水流减缓
方法1

function successThrottle(e){
    console.log("节流提交成功")
}
// 1 定义节流函数
const throttle = (fn, delay) =>{
    // 5 设置开关,初始化为true,定时器外部调用前改为false,内部的函数调用完才改回true,否则直接返回null
    let flag = true
    // 4 把setTimeout函数的结果返回给throttle函数
    return(...args) =>{
        if (!flag) {return null}   // 5
        flag = false               // 5
        // 3 设置定时器
        setTimeout(()=>{
            fn.apply(this,args)
            flag = true            // 5
        },delay)
    }
}

// 2 调用节流函数
const OnThrottle = throttle(successThrottle, 2000)
let btn2 = document.getElementById("btn2")
btn2.addEventListener("click", OnThrottle)

方法2

// 1 定义节流函数
const throttle = (fn, delay)=>{
    let lastTime = 0
    let timer
    return (...args)=>{
        let now = new Date().getTime()
        if (now - lastTime >= delay){
            fn.apply(this,args)
            lastTime = now
        }else{
            clearTimeout(timer)
            timer = setTimeout(()=>{
                fn.apply(this,args)
            },delay)
        }
    }
}

// 2 调用节流函数
const OnThrottle = throttle(successThrottle, 2000)
let btn2 = document.getElementById("btn2")
btn2.addEventListener("click", OnThrottle)

应用场景

函数节流:

  • 懒加载,监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次
  • DOM 元素的拖拽功能实现(mousemove)
  • 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
  • 计算鼠标移动的距离(mousemove)
  • Canvas 模拟画板功能(mousemove)
  • 搜索联想(keyup)

函数防抖:

  • 每次 resize/scroll 触发统计事件
  • 文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)

语法笔记:

windows对象的方法setTimeout()和clearTimeout()

setTimeout(function(){ }, time)
setTimeout("<function name()>", time)
用于在指定的毫秒数后调用函数或计算表达式

  • function处可以调用全局作用域的函数,或创建匿名函数
  • time的单位是毫秒 3000表示3秒
  • 第二种直接写已有函数的时候要加双引号,如果传入的不是一个已有函数,而是像防抖函数那里,在调用的时候再设置具体函数,则要用第一种方法,创建匿名函数,在里面调用,否则这个计时器无效

clearTimeout(id_of_settimeout)
取消由 setTimeout() 方法设置的定时操作。

  • id_of_settimeout是给setTimeout()定义的变量名称
展开语法/不定参数 …args
绑定作用域this
用flag作为开关进行判断
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值