让前端飞苦比切图仔Web前端之路

函数节流与函数防抖精析

2019-07-02  本文已影响4人  hencins

引用前人博客内容 《JavaScript高级程序》中关于函数节流概念的错误,本人也非常赞同作者关于写博客的态度。
另一篇释义清晰的文章 一定能看懂的函数防抖与函数节流

两者概念辨别

函数节流和函数防抖在一些应用场景上有重合,导致新手比较难以分辨到底谁是谁,引用文中释义准确的定义:

比如以监听一个resize事件为例,连续地多次调节窗口的大小:

所以它们的这个属性天然决定了各自适合的应用场景:

它们两者在某些场合都可以使用,但效果会有所差别。比如屏幕滚动onscroll这一块,有的站点用节流来做,可以让你一直不断的下拉屏幕,这对于快速浏览场景,找图片找新闻标题会很好;但是如果是在看某块完整内容,如一篇新闻一个章节小说,体验效果就会很差,这时就适合用防抖来做。

两者的目的都是为了节省非必要的消耗,提升响应性能和保证其他逻辑层的稳定执行(不会被大量DOM渲染或重复执行的回调事件而导致响应滞后)。

函数节流 throttle

示例代码:

<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <title>Throttle Test</title>
</head>
<body style="height:200vh;">
  <script>
    const throttle = (func = ()=>{}, interval = 250) => {
      let isFree = true;
      return function () {
        if (!isFree) return;
        isFree = false;
        setTimeout(() => { isFree = true }, interval); // 体会throttle是以一定频率来响应
        if (func) func();
      }
    }
    var scrollthrottle = throttle(() => console.log("Throttle Function"));
    document.body.onscroll = scrollthrottle;
  </script>
</body>
</html>

函数防抖 debounce

示例代码:

<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body style="height:200vh;">
  <script>
    const debounce = (func = ()=>{}, wait = 250) => {
      let timer;
      return function () {
        clearTimeout(timer);
        timer = setTimeout(() => {
          if (func) func();
        }, wait); // 体会debounce是滞后于事件响应之后的效果
      }
    }
    var scrolldebounce = debounce(() => console.log('Debounce Function'));
    document.body.onscroll = scrolldebounce;
  </script>
</body>
</html>

增添一点区别:从代码中也可以看到,在节流中回调函数可以放在setTimeout里,也可放在外。而在防抖中只能放在setTimeout里了。注意到这点区别也是在不同场合使用不同方法的原因之一。

一句话总结

节流 过程中以一定频率执行回调,以一定频率连续响应
防抖 过程完成之后执行一次回调,在一段时间内只响应一次

上一篇 下一篇

猜你喜欢

热点阅读