1. 实现
1.1 节流
// 具体实战--监控平台展示信息(websocket大量吞吐)
let throttle = (fn, timmer = 1000) => {
let prevTime = new Date();
return (...args) => {
let nowTime = new Date();
if (nowTime - prevTime > timmer) {
fn.apply(this, args);
prevTime = nowTime;
}
};
};
1.2 防抖
// 具体实战--用户输入
let debounce = (fn, offset = 1000) => {
let timer = null;
return (...args) => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, offset);
};
};
2. 使用
let count = 1;
document.addEventListener(
'scroll',
throttle((event) => {
console.log(count++, event);
}),
false
);
3. 理解
- 由于
throttle()执行了,所以返回的是return里面的函数
-
throttle里面包裹的匿名函数是实际被scroll事件调用的函数
-
return外部的变量prevTime是闭包内的变量,能被return函数内使用
-
this指针问题
- 由于
...args拿到的是数组,所以使用了apply
4. hooks写法
4.1 节流
import { useCallback, useEffect, useRef } from 'react';
const useThrottle = (fn: Function, delay: number, dep: any[] = []) => {
const { current } = useRef<{ fn: Function; prevTime: number }>({ fn, prevTime: Date.now() });
useEffect(() => {
// 若需要防抖的函数发生变动,或挂载点发生变动,重新挂载
current.fn = fn;
}, [current, fn]);
return useCallback(
(...args) => {
let nowTime = Date.now();
if (nowTime - current.prevTime > delay) {
current.fn.apply(this, args);
current.prevTime = nowTime;
}
},
[current, delay, ...dep]
);
};
export default useThrottle;
4.2 防抖
import { useCallback, useEffect, useRef } from 'react';
const useDebounce = (fn: Function, delay: number, dep: any[] = []) => {
const { current } = useRef<{ fn: Function; timer: NodeJS.Timeout | null }>({ fn, timer: null });
useEffect(() => {
// 若需要防抖的函数发生变动,或挂载点发生变动,重新挂载
current.fn = fn;
}, [current, fn]);
return useCallback(
(...args) => {
if (current.timer) {
clearTimeout(current.timer);
}
current.timer = setTimeout(() => {
current.fn.apply(this, args);
}, delay);
},
[current, delay, ...dep]
);
};
export default useDebounce;
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。