節流是指連續觸發事件但在 n 秒內只執行一次函數。

使用場景

  • 滾動加載更多
  • 鼠標移動事件
  • 按鈕頻繁點擊
  • 遊戲中的按鍵處理
function throttle(func, delay, options = {}) {
    let timeoutId = null;
    let lastTime = 0;
    const { leading = true, trailing = true } = options;
    
    return function(...args) {
        const context = this;
        const now = Date.now();
        
        // 第一次執行控制
        if (!lastTime && !leading) {
            lastTime = now;
        }
        
        const remaining = delay - (now - lastTime);
        
        if (remaining <= 0) {
            // 可以執行
            if (timeoutId) {
                clearTimeout(timeoutId);
                timeoutId = null;
            }
            lastTime = now;
            func.apply(context, args);
        } else if (trailing && !timeoutId) {
            // 設置延遲執行
            timeoutId = setTimeout(() => {
                lastTime = !leading ? 0 : Date.now();
                timeoutId = null;
                func.apply(context, args);
            }, remaining);
        }
    };
}

防抖是指觸發事件後,在 n 秒後執行函數,如果在 n 秒內又觸發了事件,則會重新計算執行時間。

使用場景

  • 搜索框輸入建議
  • 表單驗證
  • 窗口大小調整
  • 文本編輯器自動保存
function debounce(func, delay, immediate = false) {
    let timeoutId = null;
    
    return function(...args) {
        const context = this;
        
        // 清除之前的定時器
        if (timeoutId) {
            clearTimeout(timeoutId);
        }
        
        // 立即執行模式
        if (immediate && !timeoutId) {
            func.apply(context, args);
        }
        
        timeoutId = setTimeout(() => {
            // 非立即執行模式
            if (!immediate) {
                func.apply(context, args);
            }
            timeoutId = null;
        }, delay);
    };
}