面试题答案
一键面试防抖(Debounce)
- 原理:防抖是指在事件触发后的一定时间内(防抖时间),如果再次触发该事件,会重新计算时间,直到设定的时间内没有再次触发,才执行回调函数。简单来说,就是将多次操作合并为一次操作,延迟执行。
- React 中自定义 Hook 实现:
import { useCallback, useRef } from 'react';
const useDebounce = (callback, delay) => {
const timer = useRef();
return useCallback((...args) => {
if (timer.current) {
clearTimeout(timer.current);
}
timer.current = setTimeout(() => {
callback.apply(this, args);
}, delay);
}, [callback, delay]);
};
export default useDebounce;
- 优点:可以有效减少函数执行次数,适用于一些频繁触发但不需要立即响应的场景,如窗口 resize、输入框输入等,能显著提升性能。
- 缺点:如果防抖时间设置过长,可能会导致用户操作和响应之间出现明显延迟,影响用户体验。
节流(Throttle)
- 原理:节流是指在一定时间内(节流时间),无论事件触发多少次,都只会执行一次回调函数。它可以控制函数在一定时间间隔内只被调用一次,从而限制函数的执行频率。
- React 中自定义 Hook 实现:
import { useCallback, useRef } from'react';
const useThrottle = (callback, delay) => {
const lastCallTime = useRef();
return useCallback((...args) => {
const now = new Date().getTime();
if (!lastCallTime.current || now - lastCallTime.current >= delay) {
callback.apply(this, args);
lastCallTime.current = now;
}
}, [callback, delay]);
};
export default useThrottle;
- 优点:在保证一定响应频率的同时,避免了函数的过度调用,能在一定程度上平衡性能和响应速度。适用于一些需要频繁触发且需要即时反馈的场景,如滚动事件、鼠标移动事件等。
- 缺点:由于节流时间固定,即使在节流时间内事件触发很频繁,也只能执行一次回调,可能无法精确满足某些对响应及时性要求极高的场景。
在可滚动长列表场景中的应用
在 React 应用的可滚动长列表场景中,将滚动事件处理函数用防抖或节流进行包装:
import React, { useEffect } from'react';
import useDebounce from './useDebounce';
import useThrottle from './useThrottle';
const LongList = () => {
const handleScrollDebounce = useDebounce(() => {
// 滚动到某个列表项时触发的特定操作
console.log('Debounce: 执行特定操作');
}, 300);
const handleScrollThrottle = useThrottle(() => {
// 滚动到某个列表项时触发的特定操作
console.log('Throttle: 执行特定操作');
}, 300);
useEffect(() => {
window.addEventListener('scroll', handleScrollDebounce);
return () => {
window.removeEventListener('scroll', handleScrollDebounce);
};
}, [handleScrollDebounce]);
useEffect(() => {
window.addEventListener('scroll', handleScrollThrottle);
return () => {
window.removeEventListener('scroll', handleScrollThrottle);
};
}, [handleScrollThrottle]);
return (
<div style={{ height: '100vh', overflowY: 'auto' }}>
{/* 长列表内容 */}
</div>
);
};
export default LongList;
根据具体需求选择防抖或节流,如果对响应及时性要求不高,希望最大程度减少函数执行次数,可选择防抖;如果需要一定频率的即时反馈,避免过度调用,可选择节流。