在防抖这一块,可以防止用户多次快速点击造成不必要的错误,基本原理是加个延时器,在时间到来前再次点击将重新计时。采用闭包实现变量不被销毁。具体代码如下:
//方法
export const Debounce = (fn, t) => {
let delay = t || 500;
return function () {
let args = arguments;
let timer1 = null
// console.log(timer1);
if(timer1){
clearTimeout(timer1);
}
timer1 = setTimeout(() => {
fn.apply(this, args);
timer1 = null;
}, delay);
}
};
//调用
/*import {Debounce} from '@/common/debounceThrottle.js'
Debounce(() => {
//要执行的函数
}, 200)() */
但我在实际使用中有个问题,timer在每次调用后就被销毁了,每次点击 timer都会重新被赋值为 null 。最终效果只剩了延迟触发,点几次,触发几次。研究了很久都没找到原因,最后,我采用了取巧的方法,将timer提到外面,定义为全局变量。虽然效果是达到了,但之前的问题仍不知道是哪里出了问题,希望有大佬能解惑。
下面是我取巧的方法:
/**
* 函数防抖 (只执行最后一次点击)
* @param fn
* @param delay
* @returns {Function}
* @constructor
*/
let timer1 = null; //防抖,
let timer2 = null; //节流
export const Debounce = (fn, t) => {
let delay = t || 500;
return function () {
let args = arguments;
// let timer1 = null
// console.log(timer1);
if(timer1){
clearTimeout(timer1);
}
timer1 = setTimeout(() => {
fn.apply(this, args);
timer1 = null;
}, delay);
}
};
// 使用
/*import {Debounce} from '@/common/debounceThrottle.js'
Debounce(() => {
//要执行的函数
}, 200)() */
/**
* 函数节流
* @param fn
* @param interval
* @returns {Function}
* @constructor
*/
export const Throttle = (fn, t) => {
let last;
let interval = t || 500;
return function () {
let args = arguments;
let now = +new Date();
if (last && now - last < interval) {
clearTimeout(timer2);
timer2 = setTimeout(() => {
last = now;
fn.apply(this, args);
}, interval);
} else {
last = now;
fn.apply(this, args);
}
}
};
6 个回复
5***@qq.com
this指向丢失
小糊涂酒仙
单独js文件封装 最简单方法,没有闭包带来的内存泄漏问题
也没有通过call 和 apply 来解决 this指向问题,代码还是写的实用,简单运行流畅的好。
zhangdaren
特来点赞,我发现通过return函数的形式,用得不生效。。不知为啥
2022-11-09 16:52
luch
还得继续努力啊!
<br>
先搞懂闭包!
<br>
js 命名除了Class 类都是小驼峰
<br>
现在工具库都使用lodash.js,可以看一下。
<br>
嗨哆嚒 (作者)
谢谢
2020-09-08 09:32
ihshan12 - 好人一个
// 使用
/import {Debounce} from '@/common/debounceThrottle.js'
Debounce(() => {
//要执行的函数
}, 200)() /
使用方式不对,你要把方法返回的函数绑定到事件中
<view @click="yourEvent">防抖</view>
methods:{
yourEvent:Debounce(() => {
//要执行的函数
}, 200)
}
嗨哆嚒 (作者)
谢谢
2020-09-08 09:32
船帆
需要节流的函数需要传参怎么办呢
1***@qq.com
首先不能用剪头函数,使用的时候也是。这样会导致this指向有问题的
小糊涂酒仙
这里可以使用箭头函数,因为在调用的时候用的是外部的this ,也就是实例的this。不用内部函数的this就可以使用箭头函数,要是使用内部的this指向就用普通函数,灵活运用就可以了,主要看使用的场景
2021-09-06 01:12
小糊涂酒仙
如果觉得有问题,你可以试试在调用的部打印this,看看是不是和外部this指向一样,学艺不精
2021-09-06 01:14