Skip to content

Instantly share code, notes, and snippets.

@HydrangeaPurple
Last active September 6, 2021 13:14
Show Gist options
  • Save HydrangeaPurple/41bc2a93cc983358317311c6a55e0cd2 to your computer and use it in GitHub Desktop.
Save HydrangeaPurple/41bc2a93cc983358317311c6a55e0cd2 to your computer and use it in GitHub Desktop.
Typescript 使用函数防抖和节流
/**
* 函数防抖包装函数
* @author
* @export
* @class Debounced
*/
export class Debounced {
/**
* @param func 需要包装的函数
* @param delay 延迟时间,单位ms
* @param immediate 是否默认执行一次(第一次不延迟)
*/
public use = (func: Function, delay: number, immediate: boolean = false): Function => {
let timer: number | undefined;
return (...args: any) => {
if (immediate) {
func.apply(this, args); // 确保引用函数的指向正确,并且函数的参数也不变
immediate = false;
return;
}
clearTimeout(timer);
timer = window.setTimeout(() => {
func.apply(this, args);
}, delay);
};
};
}
/*
例子
export class Test
private count: number = 1
包装后的防抖函数
private debouncedUse: Function = new Debounced().use(this.request, 1000)
原始函数
private request(params: any) {
console.log('this的指向', this);
console.log('参数', params);
console.log(this.count++)
}
调用包装后的防抖函数
private handelClickByDebounced() {
this.debouncedUse(123)
}
*/
<template>
<div id="debounced-test">
<v-button @click="handelClickByDebounced">防抖</v-button>
<v-button @click="handelClickByThrottle" type="success">节流</v-button>
<v-button @click="changeStopThrottle(throttle.stop)" type="warning">
{{ throttle.stop ? '开启' : '关闭' }}节流
</v-button>
<v-button @click="destroyThrottle" type="danger">销毁节流函数</v-button>
</div>
</template>
<script lang="ts">
import { Debounced, Throttle } from '@/utils'
import { Vue, Component } from 'vue-property-decorator'
@Component
export default class DebouncedTest extends Vue {
private count: number = 1
private debouncedUse: Function = new Debounced().use(this.request, 1000)
private throttle = new Throttle()
private throttleUse: Function = this.throttle.use(this.request, 1000)
private request(params: any) {
console.log('this的指向', this);
console.log('参数', params);
console.log(this.count++)
}
// 防抖调用
private handelClickByDebounced() {
this.debouncedUse(123)
}
// 节流调用
private handelClickByThrottle() {
this.throttleUse('截流函数')
}
// 停止 | 开启节流函数
private changeStopThrottle(action: boolean) {
action ? this.throttle.open() : this.throttle.close()
}
// 销毁节流函数
private destroyThrottle() {
this.throttle.destroy()
}
}
</script>
/**
* 函数节流包装函数
* @author
* @export
* @class Throttle
*/
export class Throttle {
private timer: number | undefined;
private stop: boolean = false;
private death: boolean = false;
/**
* @param func 需要包装的函数
* @param delay 延迟时间,单位ms
* @param immediate 是否默认执行一次(第一次不延迟)
*/
public use(func: Function, delay: number, immediate: boolean = false): Function {
let flag = true;
const self = this;
return (...args: any) => {
if (this.death) {
func.apply(this, args);
return;
}
if (this.stop) {
func.apply(this, args);
return;
}
if (immediate) {
func.apply(this, args);
immediate = false;
return;
}
if (!flag) {
return;
}
flag = false;
self.timer = window.setTimeout(() => {
func.apply(this, args);
flag = true;
}, delay);
};
}
/**
* 销毁
*
* @memberof Throttle
*/
public destroy() {
this.death = true;
this.stop = true;
if (!!this.timer) {
clearTimeout(this.timer);
this.timer = undefined;
}
}
/**
* 开启
*
* @memberof Throttle
*/
public open() {
if (!this.death) {
this.stop = false;
}
}
/**
* 关闭
*
* @memberof Throttle
*/
public close() {
this.stop = true;
}
}
/*
例子
export class Test {
private count: number = 1
private throttle = new Throttle()
private throttleUse: Function = this.throttle.use(this.request, 1000)
private request(params: any) {
console.log('this的指向', this);
console.log('参数', params);
console.log(this.count++)
}
节流调用
private handelClickByThrottle() {
this.throttleUse('截流函数')
}
停止 | 开启节流函数
private changeStopThrottle(action: boolean) {
action ? this.throttle.open() : this.throttle.close()
}
销毁节流函数
private destroyThrottle() {
this.throttle.destroy()
}
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment