节流与防抖

493 阅读2分钟

节流

使用场景:鼠标不断点击触发,mousedown(单位时间内只触发一次)

原理:单位时间内连续触发,但是只会执行一次,比如事件在300秒内不断触发点击事件,那么只会执行一次,到下一个300s开始计时的时候,就会在下一个300s内再执行一次;也就是说600s连续触发事件但是只会执行2次。

throttle(func, wait = 300, immediate = true) {      if (immediate) {        if (!flag) {          flag = true;          // 如果是立即执行,则在wait毫秒内开始时执行          typeof func === 'function' && func();          setTimeout(() => {            flag = false;          }, wait);        }      } else {        if (!flag) {          flag = true          // 如果是非立即执行,则在wait毫秒内的结束处执行          setTimeout(() => {            flag = false            typeof func === 'function' && func();          }, wait);        }      }    }

防抖

使用场景:如搜索框,用户在输入的时候使用change事件去调用搜索,如果用户每一次输入都去搜索的话,就会消耗很大的服务器资源。如果每次用户停止输入后,延迟超过一定时间时,才去请求服务器的话,会节省服务器资源,提升用户体验。

原理:事件回调函数在一段时间(300毫秒)后才执行,如果在这段时间内再次调用则重新从0开始计算到300毫秒的时间,当预定的时间内没有再次调用该函数,则执行事件回调函数

debounce(func, wait = 300, immediate = false) {      // 清除定时器      if (timeout !== null) clearTimeout(timeout);      // 立即执行,此类情况一般用不到      if (immediate) {        var callNow = !timeout;        timeout = setTimeout(function () {          timeout = null;        }, wait);        if (callNow) typeof func === 'function' && func();      } else {        // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法       timeout = setTimeout(function () {         typeof func === 'function' && func();       }, wait);     }},

整体代码

<template>  <div class="hello">    <el-input style="width:160px;" placeholder="请输入内容" @input="setValueNull" v-model="name" clearable @clear="setValueNull"></el-input>    <el-button @click="btnClick">点我</el-button>  </div></template><script>let timeout, flag;export default {  name: 'HelloWorld',  data() {    return {      name: ''    }  },  methods: {    setValueNull() {        this.debounce(this.getTableListData,1000)    },    btnClick() {      this.throttle(this.getTableListData, 1000)    },    getTableListData() {      console.log(123);    },    // 防抖    debounce(func, wait = 300, immediate = false) {      // 清除定时器      if (timeout !== null) clearTimeout(timeout);      // 立即执行,此类情况一般用不到      if (immediate) {        var callNow = !timeout;        timeout = setTimeout(function () {          timeout = null;        }, wait);        if (callNow) typeof func === 'function' && func();      } else {        // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法        timeout = setTimeout(function () {          typeof func === 'function' && func();        }, wait);      }    },    // 节流    throttle(func, wait = 300, immediate = true) {      if (immediate) {        if (!flag) {          flag = true;          // 如果是立即执行,则在wait毫秒内开始时执行          typeof func === 'function' && func();          setTimeout(() => {            flag = false;          }, wait);        }      } else {        if (!flag) {          flag = true          // 如果是非立即执行,则在wait毫秒内的结束处执行          setTimeout(() => {            flag = false            typeof func === 'function' && func();          }, wait);        }      }    }  }}</script>