概念:
节流:当持续触发事件时,保证一定时间段内只调用一次事件处理函数。
防抖:当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
应用场景:
节流:监听浏览器滚动、多次点击情况下可以采用该功能。
参考地址:blog.csdn.net/stupid_musc…
// 防抖
export function PromiseDebounce(time = 200, delayTime = 250) {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const original = descriptor.value;
const debounceFn = function () {
let timer = null;
const execFn = function (...args: any) {
if (timer) clearTimeout(timer);
timer = setTimeout(async () => {
const data = await Promise.all([
original.call(this, ...args),
new Promise((resolve) => {
setTimeout(resolve, time);
}),
]);
return data[0];
}, time);
};
return execFn;
};
descriptor.value = debounceFn();
return descriptor;
}
}
/**
* 网络请求节流装饰器,对网络请求进行锁操作,网络请求结束之后释放
* @param time 等网络请求结束和设置时间完成之后释放节流
* @param delayTime 延迟被装饰方法的触发时间
*/
export function PromiseThrottle(time = 200, delayTime = 500) {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const original = descriptor.value;
const throttleFn = function () {
let status = '';
const execFn = async function (...args: any) {
if (status === 'ing') {
return;
}
status = 'ing';
try {
const data = await Promise.all([
original.call(this, ...args),
new Promise((resolve) => {
setTimeout(resolve, time);
}),
]);
return data[0];
} finally {
setTimeout(() => {
status = '';
}, delayTime);
}
};
return execFn;
};
descriptor.value = throttleFn();
return descriptor;
};
}
以下示例使用在多次点击按钮的情况下,故采用反抖的方式对方法进行处理。
未采用装饰器之前的写法
import { Options, Vue } from 'vue-class-component'
export default class demo extends Vue {
data(){
return {
clickTime: new Date().getTime()
}
}
save(){
let delta = Date.now() - this.clickTime //计算两次点击时间差
this.clickTime = Date.now()
if (delta > 0 && delta <= 250) {
//双击事件
return
}
console.log("save")
}
}
采用装饰器之后的写法
import { Options, Vue } from 'vue-class-component'
import { PromiseThrottle } from "./common.ts"
export default class demo extends Vue {
@PromiseThrottle(500)
save(){
console.log("save")
}