防抖、节流 | 青训营笔记

64 阅读2分钟

这是我参与「 第五届青训营 」伴学笔记创作活动的第 10 天

防抖、节流

一、防抖

函数防抖动(debounce):防止在短时间内过于频繁的执行相同的任务。 当短时间内的频繁是不必要的时候,就可以考虑去抖动,避免资源浪费,或造成不好体验。

函数防抖动的原理,主要是利用一次性定时器,延迟任务的执行,在延迟这段时间内, 如果任务再次被触发,则通过 clearTimeout 销毁上一次产生的定时器, 因为定时器的被销毁,之前被延迟执行的任务也会随之被取消执行。 这样就实现了在一定时间内,只执行一次任务。这一次的执行通常是最后一次的触发, 因为此前的触发因为定时器的销毁而被取消了。

  1. 了解防抖的过程

当事件触发时,相应的函数并不会⽴即触发,⽽是会等待⼀定的时间; 当事件密集触发时,函数的触发会被频繁的推迟; 只有等待了⼀段时间也没有事件触发,才会真正的执⾏响应函数; 2. ### 防抖的应⽤场景

输⼊框中频繁的输⼊内容,搜索或 者提交信息; 频繁的点击按钮,触发某个事件; 监听浏览器滚动事件,完成某些特 定操作; ⽤户缩放浏览器的resize事件; 3. ### 实现防抖的思路

优化⼀:优化参数和this指向 优化⼆:优化取消操作(增加取消功能) 优化三:优化⽴即执⾏效果(第⼀次⽴即执⾏) 优化四:优化返回值

  1. ⼿写防抖

//引⼊underscore库 
<script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore- umd-min.js">
</script>
<script>   
const inputEl = document.querySelector("inpit")   
let counter = 1   
inputEl.oninput = _.debounce(function() {
  console.log(`发送⽹络请求${counter++}:`, this.value, event)   
}, 1000) 
</script>

//基本实现
function mydebounce(fn, delay) {
  //⽤于记录上⼀次事件触发的timer
  let timer = null
  //触发事件时执⾏的函数
  const _debounce = () => {
    //如果再次触发事件, 那么需要取消上⼀次的事件
    if (timer) clearTimeout(timer)
    //延迟执⾏fn函数(传⼊的回调函数)
    timer = setTimeout(() => {
      fn()
      timer = null
      //执⾏完
    }, delay)
  }
  //返回新的函数
  return _debounce
}
//优化this、event
function mydebounce(fn, delay) {
  //⽤于记录上⼀次事件触发的timer
  let timer = null
  //触发事件时执⾏的函数
  const _debounce = function (...args) {
    //如果再次触发事件, 那么需要取消上⼀次的事件
    if (timer) clearTimeout(timer)
    //延迟执⾏fn函数(传⼊的回调函数)
    timer = setTimeout(() => {
      fn.apply(this, args)
      //this是inputEl
      timer = null //执⾏完
    }, delay)
  }
  //返回新的函数
  return _debounce
}

二、节流

  1. 等待⼀段时间执⾏函数, 即使不断触发事件

  2. ⼿写节流函数基本功能

function mythrottle(fn, interval) {   
  let startTime = 0   
  const _throttle = function() {     
    const nowTime = new Date().getTime()     
    const waitTime = interval - (nowTime - startTime)     		if (waitTime <= 0) {       
      fn()       
      startTime = nowTime     
    }  
  }   
  return _throttle 
}