防抖函数节流函数

吐槽君 分类:javascript

防抖和节流主要用于 scroll, mousemove ,resize, 但有些时候,我们并不希望再时间持续触发的国成中,那么频繁的去执行函数,
场景: 输入框持续输入,将输入内容持续校验。
防抖是控制次数, 节流是控制频率。

防抖(debounce)

防抖是指触发事件后在 n 秒内函数只执行一次, 如果在 n 秒内又触发了事件, 则会重新计算函数执行时间。

需求描述:
函数防抖, 这里的抖动就是执行的意思, 而一般的抖动都是持续的, 多次的。 假设函数持续多次执行, 我们希望让它冷静下来执行。 也就是当持续触发事件的时候, 函数是完全不执行的,等最后一次触发结束的一段时间之后,再去执行,

分解一下需求,

  • 持续触发不执行
  • 不触发的一段时间执行
 function debounce(func, deplay){
     let timeout ;
   return  function(){
         clearTimeout(timeout)
         timeout  = setTimeout(function(){
             func.apply(this, arguments)
         }, deplay)
         
     }
 }
 
 // 用法:
 box.onmousemove = debounce(function(e){
     box.innerHtml = `${e.clientX}, ${e.clientY}`
 }, 1000)

 

节流 (throttle)

节流, 就是指连续触发事件但是在 n 秒钟只执行一次函数。 节流会稀释函数的执行频率。

对于节流, 一般有两种方式实现, 分别是时间戳版和定时器版

同样分解一下

  • 持续触发并不会执行多次
  • 到一定时间再去执行

思考:持续触发, 并不会执行, 但是到时间了就会执行。 抓取一个关键的点:就是执行的时机, 要做到控制执行的时间, 我们可以通过一个开发, 与定时器 setTimeout 结合完成。

函数执行的前提条件是开关打开, 持续触发时,持续关闭开关, 等到 setTimeout 到时间了, 再把开关打开 ,函数就会执行了。

时间戳版:

function throttle(func, wait) {
    let pervious = 0
    return function(){
     let now = Date.now();
     let context = this;
     let args = arguments;
     if(now -previous > wait) {
         func.apply(context, args);
         perviose = npw
     }
    }
}
 

定时器版本

  function throttle(func, await){
      let run = true 
      return function () {
          if(!run) {
              return // 如果开关关闭了, 那就直接不执行下边的代码
          }
          run = false // 持续触发的话, run 一直是false, 就会停在上边的判断哪里
          setTimeout(()=>{
              func.apply(this,arguments)
              run = true //定时器到时间之后,会把开关打开 ,我们的函数就会被执行, 
          },delay)
      }
  }

// 调用的时候:

box.onmousemove = throttle(function (e) {
    box.innerHtml = `${e.clientX}, ${e.clientY}`
},1000)
 

总结

防抖和节流巧妙地用了 setTimeout, 来控制函数执行的时间, 优点很明细 ,可以节约性能, 不至于多次触发复杂的业务逻辑而造成页面的卡顿。

引申

call apply bind 的区别

  • call
  • apply
  • bind
一线大厂高级前端编写,前端初中阶面试题,帮助初学者应聘,需要联系微信:javadudu

回复

我来回复
  • 暂无回复内容