函数的节流与防抖
防抖
防抖是指在一定的时间内再次触发此事件,会清空上次的事件重新开始,如果制定的时间内没有再次触发,那么这个事件才会执行。
function showLog() {
console.log('show');
}
/*
* 防抖 思路:
* 先开启一个定时任务执行,定时任务完成后则清空;当再调用时,如果定时任务仍存在则清空原来任务,创建新的定时任务
* */
function debounce(fn, space) {
let task = null;
return function (){
if(task) {
clearTimeout(task);
}
task = setTimeout(fn.apply(this, arguments), space);
/*apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。
你也可以使用 arguments对象作为 argsArray 参数。 arguments 是一个函数的局部变量。
*/
}
}
// 使用
let debounceShowLog = debounce(showLog, 3000);
debounceShowLog()
这里说一下闭包
var bibao = function () {
var counter = 0;
return function () {
return counter += 1;}
};
var add=bibao()//此时的add接收的为 return counter+=1
console.log(add())
console.log(add())
console.log(add())
//结果为1 2 3
闭包的形成:内部函数引用了外部函数的数据(这里为 counter),因此在add=bibao(),则会把这个counter保存在add中,函数执行完,counter并不会被销毁。
注意: 为什么上面这段代码没有直接写的 function add (){…} 而是把function赋值给了变量add呢?
我们通常会想当然的认为每次调用 add() 都会重走一遍add()中的代码块, 但其实不然。
注意add方法中的return, 它return的并不是1,2,3这样的数值,而是return了一个方法,并且把这个方法赋值给了add变量。
那么在这个function自运行一遍之后,其实最后赋值给add的是return counter += 1 这段代码。
所以后面每次调用add() 其实都是在调用return counter += 1。
再结合文章之前所说的, 闭包会持有父方法的局部变量并且不会随父方法销毁而销毁, 所以这个counter其实就是来自于第一次function执行时创建的变量
在vue学习中使用防抖的案例
coderwhy的supermall项目中
//Home.vue
mounted () {
// 3.监听item中图片加载完成
const refresh = this.debounce(this.$refs.scroll.refresh,200)
this.$bus.$on('itemImageLoad',()=>{
// console.log('-----');
// this.$refs.scroll.refresh()
refresh()
})
},
methods: {
// 防抖函数
// debounce(func,delay)
debounce(func,delay){
let timer = null;
return function(...args){
if(timer) clearTimeout(timer);
timer =setTimeout(() => {
func.apply(this,args)
}, delay);
}
},
}
//Score.vue
methods: {
refresh(){
console.log('refresh调用');
this.scroll && this.scroll.refresh &&this.scroll.refresh()
}
}
节流
节流是指在一定的时间同一事件只会触发一次,只有超过了这个时间才会再次触发。
/*
* 节流 思路:
* 先开启一个定时任务执行,定时任务完成后则清空,当再调用时,如果定时任务仍存在则不执行任何操作
* */
function throttle(fn, space) {
let task = null;
return function () {
if(!task) {
task = setTimeout(function () {
task = null;
fn.apply(this, arguments);
}, space);
}
}
}
let throttleShowLog = throttle(showLog, 3000);
总的来说:任何东西被频繁的调用都有可能需要防抖或者节流去优化
参考文章