首页
归档
笔记
树洞
搜索
友言

文章详情

Interesting People Record Interesting.

/ JavaScript / 文章详情

什么是防抖和节流,他们的应用场景有哪些

Sonder
2020-03-20
3907字
10分钟
浏览 (3.3k)

节流(throttle):固定时间内事件只执行一次

在固定时间内事件只执行一次。应用场景:高频的监听事件、滚动事件、input 框实时搜索并发送请求展示下拉列表,每隔一秒发送一次请求 (也可做防抖)

节流可以比作过红绿灯,每等一个红灯时间就可以过一批

代码如下,可以看出来节流重在加锁 timer=timeout

复制代码
<html>
<head>
   <title>节流</title>
</head>
<body>
   <button onclick="clickBtn1()">使用时间戳</button>
   <button onclick="clickBtn2()">使用定时器</button>
<script type="text/javascript">


   let clickBtn1 = throttle1(function(){
       console.log("使用时间戳;无论你高频点多少次都会在n秒内执行一次,节流会稀释函数的执行频率")
   });

   let clickBtn2 = throttle2(function(){
       console.log(12312)
   });
   //高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率

   //使用时间戳
   function throttle1(fn,wait = 300) {
       let time = 0;
       return function(){
           let _this = this;
           let args = arguments;
           let now = Date.now();
           if(now - time > wait) {
               fn.apply(_this,args);
               time = now;
           }
       }
   }

   // 使用定时器
   function throttle2(fn,wait = 300) {
       let timer;

       return function(){
           let _this = this;
           let args = arguments;

           if(!timer) {
               timer = setTimeout(function(){
                   timer = null;
                   fn.apply(_this,args);
               },wait);
           }
       }
   }
</script>
</body>
</html>

防抖(debounce):最后一个人说了算

多次事件只执行最后一次。应用场景:登录、发短信,调整浏览器窗口大小,文本编辑器实时保存,输入框输入事件,鼠标移动

防抖可以比作等电梯,只要有一个人进来,就需要再等一会儿。业务场景有避免登录按钮多次点击的重复提交。

代码如下,可以看出来防抖重在清零 clearTimeout(timer)

复制代码
<html>
<head>
   <title>防抖</title>
</head>
<body>

<button onclick="clickBtn(1)">按钮</button>
<script type="text/javascript">
   let clickBtn = debounce(function(i){
       console.log("触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间")
   });
   //防抖,触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
   function debounce(fn,wait = 300) {
       let timer;
       return function(){
           let _this = this;
           let args = arguments; // 是一个对应于传递给函数的参数的类数组对象
           if(timer) { clearTimeout(timer) }
           timer = setTimeout(function(){
               fn.apply(_this,args);
           },wait);
       }
   }
       // 拉扯你的浏览器窗口
       // window.onresize  = debounce(function(){
       //     console.log("resize")
       // });
</script>
</body>
</html>

Vue事件中使用方法

复制代码
/**
 * utils/index.js
 * 节流
 * @param fn
 * @param wait
 * @returns {(function(): void)|*}
 */
export function throttle(fn,wait = 300) {
    let time = 0;
    return function(){
        let _this = this;
        let args = arguments;
        let now = Date.now();
        if(now - time > wait) {
            fn.apply(_this,args);
            time = now;
        }
    }
}
复制代码
import {throttle} from "@/utils"

methods: {
   Send:throttle(function(id,name){
       // ...code
   })
}

不使用导入

复制代码
function debounce(fn,wait = 500) {
  let timer;
  return function(){
    let _this = this;
    let args = arguments; // 是一个对应于传递给函数的参数的类数组对象
    if(timer) { clearTimeout(timer) }
    timer = setTimeout(function(){
      fn.apply(_this,args);
    },wait);
  }
}
export default {
  methods: {
      loadData() {
        this.getData(this)
    }
    getData: debounce(that => {
      that.limit += 10;
  }
}

如果是点击事件的话

复制代码
<button @click="getArticleOrder(item)">点击</button>
复制代码
methods: {
 // 解决获取不到this的问题
 //Duplicate keys detected: 'orderIndex'. This may cause an update error.
 setArticleOrder: debounce(function (...args) {
   this.getArticleOrderDebounce(...args)
 }),
 setArticleOrderDebounce(order) {
   if (order === this.orderIndex) return
   this.orderIndex = order
 }
}
下一篇 / jQ常见事件

🎯 相关文章

💡 推荐文章

🕵️‍♂️ 评论 (0)