防抖与节流在实际项目基本都会用到。
防抖
定义
:防抖(Debounce) 指的是触发事件后n秒后才能执行函数,如果在n秒内触发了事件,则会重新计算执行时间。
常见场景
:点击按钮、拍照、下拉触底加载下一页等。持续触发输入事件时,并不会立即执行func函数,而是在指定时间delay中没有再次触发事件时,才会进行延时执行func函数。
export function debounce(fn, delay = 200) {
let timer: any = null;
return function () {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.call(this, ...arguments)
}, delay)
}
}
例子:监听窗口resize
react监听resize变化后移除监听事件
useEffect(() => {
window.addEventListener('resize', debounce(handleResize));
return () => {
window.removeEventListener('resize', handleResize)
}
}, [])
未进行防抖前,每次resize间距200毫秒会进行打印一次信息
import { debounce } from '@/utils/commom';
import { useEffect } from 'react';
import yayJpg from '../assets/yay.jpg';
import './index.less';
export default function HomePage() {
const handleResize = () => {
console.log('handleResize');
}
useEffect(() => {
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize)
}
}, [])
return (
<div>
<h2>Yay! Welcome to umi!</h2>
<p>
<img src={yayJpg} width="388" />
</p>
<p>
To get started, edit <code>pages/index.tsx</code> and save to reload.
</p>
<div className='box-test'>
jjjjjj
</div>
</div>
);
}
进行防抖后,在最后一次后的200毫秒进行触发,打印一次信息
import { debounce } from '@/utils/commom';
import { useEffect } from 'react';
import yayJpg from '../assets/yay.jpg';
import './index.less';
export default function HomePage() {
const handleResize = () => {
console.log('handleResize');
}
useEffect(() => {
window.addEventListener('resize', debounce(handleResize));
return () => {
window.removeEventListener('resize', handleResize)
}
}, [])
return (
<div>
<h2>Yay! Welcome to umi!</h2>
<p>
<img src={yayJpg} width="388" />
</p>
<p>
To get started, edit <code>pages/index.tsx</code> and save to reload.
</p>
<div className='box-test'>
jjjjjj
</div>
</div>
);
}
节流
定义
:节流(Throttle) 指的是连续触发事件但是在n秒中只执行一次函数。即不管你在指定时间内触发多少次函数,但是它只执行一次事件。(只有一次生效)
常见场景
:即时查询。在持续进行触发输入事件时,并不会立即执行func的函数请求,而是每隔指定的delay时间后才会执行一次func函数,不管这段时间内你点击了多少次。
export function throttle(fn, delay = 200) {
let timer: any = null;
return function () {
if (!timer) {
timer = setTimeout(() => {
clearTimeout(timer);
timer = null;
fn.call(this, ...arguments);
}, delay)
}
}
}
例子:每间隔2000毫秒执行一此打印信息
import { debounce, throttle } from '@/utils/commom';
import { useEffect } from 'react';
import yayJpg from '../assets/yay.jpg';
import './index.less';
export default function HomePage() {
const handleResize = () => {
console.log('handleResize');
}
useEffect(() => {
window.addEventListener('resize', throttle(handleResize, 2000));
return () => {
window.removeEventListener('resize', handleResize)
}
}, [])
return (
<div>
<h2>Yay! Welcome to umi!</h2>
<p>
<img src={yayJpg} width="388" />
</p>
<p>
To get started, edit <code>pages/index.tsx</code> and save to reload.
</p>
<div className='box-test'>
jjjjjj
</div>
</div>
);
}