什么是函数防抖
一个原本延迟N秒执行的函数在执行前被反复触发时,重新计算延时。
最简单的实现方法
App.vue
<template>
<div>
<button @click="debounceTest('函数防抖')">模拟防抖事件的触发</button>
</div>
</template>
<script>
let timerId = null;
export default {
methods: {
debounceTest(message) {
console.log("按钮被单击了。。。", timerId);
if (timerId) {
clearTimeout(timerId);
timerId = null;
}
timerId = setTimeout(() => {
console.log("执行防抖函数代码:", message);
}, 1000);
},
},
};
</script>
虽然可以试下防抖,但是没有复用性,如果另一个函数也需要防抖,还需要重新写一份。
封装一个工具函数
App.vue
<template>
<div>
<button @click="debounceTest('函数防抖')">模拟防抖事件的触发</button>
</div>
</template>
<script>
import util from './utils'
console.log(util)
export default {
methods: {
debounce: util.debounce,
debounceTest(message) {
this.debounce(()=>{
console.log("执行防抖函数代码:", message);
}, 2000)()
},
},
};
</script>
util.js
let timerId = null;
function debounce(fn, timerForWait=1000) {
console.log('发起了调用请求');
return function() {
if (timerId) {
clearTimeout(timerId);
}
timerId = setTimeout(() => {
fn()
}, timerForWait);
}
}
export default {debounce};
上面的写法还是有点缺陷,
- 计时器作为模块内部变量,所有函数公用一个计时器,还是无法实现公用。
- 函数作为参数的传递方式不是很优雅
最终版
util.js
function debounce(fn, timerForWait=1000) {
console.log('发起了调用请求')
return function() {
if (fn.timerId) {
clearTimeout(fn.timerId);
}
fn.timerId = setTimeout(() => {
fn(...arguments)
}, timerForWait);
}
}
export default {debounce};
App.vue
<template>
<div>
<button @click="debounce(debounceTest, 2000)('函数防抖',',2秒后执行')">模拟防抖事件的触发</button>
<button @click="debounce(debounceTest2, 1000)('函数防抖2',',2秒后执行')">模拟防抖事件的触发</button>
</div>
</template>
<script>
import util from './utils'
export default {
methods: {
debounce: util.debounce,
debounceTest(message, time) {
console.log("执行防抖函数代码:", message+time);
},
debounceTest2(message, time) {
console.log("执行防抖函数2代码:", message+time);
},
},
};
</script>