Last active
September 6, 2021 13:14
-
-
Save HydrangeaPurple/41bc2a93cc983358317311c6a55e0cd2 to your computer and use it in GitHub Desktop.
Typescript 使用函数防抖和节流
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 函数防抖包装函数 | |
* @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) | |
} | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 函数节流包装函数 | |
* @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