面试题---区别函数节流与防抖
1. 事件高频触发处理的问题
- 如果更新界面 => 界面更新卡顿
 - 如果发送ajax请求 => 发送了很多没必要的请求
 
2. 解决办法
- 函数节流
 - 函数防抖
 
3. 区别:
-  
节流函数 (throttle):
- 接受两个参数:需要节流的回调函数
callback和延迟时间delay。 - 通过保存上一次处理事件的时间
start,确保在连续触发事件时,只有当当前时间与上一次处理事件的时间差大于设定的延迟时间delay时,才会执行回调函数callback。 
 - 接受两个参数:需要节流的回调函数
 -  
防抖函数 (debounce):
- 同样接受两个参数:需要防抖的回调函数
callback和延迟时间delay。 - 每当事件触发时,如果存在尚未执行的定时器,则清除它,然后重新启动一个延迟时间为
delay的新定时器。 - 只有当事件触发后,在指定延迟时间内没有再次触发事件时,才会执行回调函数
callback。 
 - 同样接受两个参数:需要防抖的回调函数
 
简单来讲:当事件高频发生很多次时, 防抖只执行最后一次, 而节流执行少量几次
4. 应用场景
节流: 窗口调整(resize)/ 页面滚动(scroll)/ OM元素的拖拽功能实现(mousemove)
防抖: 输入搜索联想功能
5.自定义函数节流与防抖
// 节流函数 (throttle)
function throttle(callback, delay) {
    let start = 0; // 用于保存处理事件的时间,初始值为0,保证第一次会执行
    // 返回事件监听函数 => 每次事件发生都会执行此返回的函数
    return function(event) {
        console.log('-- throttle --');
        // 发生事件的当前时间
        const current = Date.now();
        // 与上一次处理事件的时间差大于delay的时间
        if (current - start > delay) {
            // 执行处理事件的函数
            callback.call(event.target, event);
            // 保证当前时间为最新的处理事件时间
            start = current;
        }
    }
}
// 防抖函数 (debounce)
function debounce(callback, delay) {
    // 返回事件监听函数 => 每次事件发生都会执行此返回的函数
    return function(event) {
        console.log('-- debounce --');
        // 如果还有未执行的定时器,清除它
        if (callback.timeoutId) {
            clearTimeout(callback.timeoutId);
        }
        // 启动延迟delay的定时器,并保存定时器id
        callback.timeoutId = setTimeout(() => {
            // 执行处理事件的函数
            callback.call(event.target, event);
            // 删除保存的定时器id
            callback.timeoutId = null;
        }, delay);
    }
} 
要使用这两个工具函数,可以这样调用它们:
// 假设有一个需要节流的scroll事件处理器
const handleScrollThrottled = throttle(handleScroll, 200);
window.addEventListener('scroll', handleScrollThrottled);
// 假设有一个需要防抖的resize事件处理器
const handleResizeDebounced = debounce(handleResize, 500);
window.addEventListener('resize', handleResizeDebounced);