防抖
使用场景:如搜索框,用户在输入的时候使用change事件去调用搜索,如果用户每一次输入都去搜索的话,就会消耗很大的服务器资源。如果每次用户停止输入后,延迟超过一定时间时,才去请求服务器的话,会节省服务器资源,提升用户体验。
原理:事件回调函数在一段时间(300毫秒)后才执行,如果在这段时间内再次调用则重新从0开始计算到300毫秒的时间,当预定的时间内没有再次调用该函数,则执行事件回调函数
代码示例:
/**
* 防抖
* @param {Function} func 要执行的回调函数
* @param {Number} wait 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
let timeout;
export function 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); } }
在vue封装并在main.js注册全局,页面调用如下:
<template>
<el-input style="width:160px;" placeholder="请输入内容" @input="setValueNull" v-model="query.name" clearable @clear="setValueNull"></el-input>
</template>
<script>
export default { methods:{ //监听用户输入值变化,延迟调用请求函数(getTableListData) setValueNull(){ this.debounce(this.getTableListData) } } } </script>
节流
使用场景:鼠标不断点击触发,mousedown(单位时间内只触发一次)
原理:单位时间内连续触发,但是只会执行一次,比如事件在300秒内不断触发点击事件,那么只会执行一次,到下一个300s开始计时的时候,就会在下一个300s内再执行一次;也就是说600s连续触发事件但是只会执行2次。
代码示例:
/**
* 节流
* @param {Function} func 要执行的回调函数
* @param {Number} wait 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
let timer, flag;
export function throttle(func, wait = 300, immediate = true) { if (immediate) { if (!flag) { flag = true; // 如果是立即执行,则在wait毫秒内开始时执行 typeof func === 'function' && func(); timer = setTimeout(() => { flag = false; }, wait); } } else { if (!flag) { flag = true // 如果是非立即执行,则在wait毫秒内的结束处执行 timer = setTimeout(() => { flag = false typeof func === 'function' && func(); }, wait); } } };
结语
他们的区别在于,使用时间戳实现的节流函数会在第一次触发事件时立即执行,以后每过 wait 秒之后才执行一次,并且最后一次触发事件不会被执行;而定时器实现的节流函数在第一次触发时不会执行,而是在 wait秒之后才执行,当最后一次停止触发后,还会再执行一次函数。
希望对大家学习有帮助,能力有限,如果有错误的欢迎指出,共同进步。