首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

JavaScript 定時器寫法不規範導致重複執行問題

     編輯:程式設計疑難解答

問題現象

開發者將 setInterval 定時器放置於 chgCol() 函數內部,導致每次呼叫該函數都會建立新的定時器,造成:

  • 多個定時器並行執行
  • 色彩變換頻率加快、失控
  • 記憶體洩漏(舊定時器未清除)

錯誤程式碼示例

function chgCol() {
    // 業務邏輯...
    setInterval(function() {
        chgCol(); // 遞迴呼叫,且每次都新建定時器
    }, 1000);
}
// 外部呼叫
chgCol(); // 第一次建立定時器
// 1 秒後定時器觸發 -> 再次呼叫 chgCol() -> 再建立一個定時器...指數級增長

正確寫法:定時器提升至外層

// 定時器變數提升至模組/類別層級
let colorTimer = null;

function startColorChange() {
    // 防止重複啟動
    if (colorTimer) return;
    
    colorTimer = setInterval(() => {
        chgCol(); // 僅執行色彩變換邏輯
    }, 1000);
}

function stopColorChange() {
    if (colorTimer) {
        clearInterval(colorTimer);
        colorTimer = null;
    }
}

function chgCol() {
    // 純色彩變換邏輯,無定時器建立
    document.body.style.backgroundColor = getRandomColor();
}

關鍵原則

  1. 定時器與業務邏輯分離:setInterval/setTimeout 應在初始化或啟動函數中建立,不應置於被重複呼叫的函數內
  2. 單一實例模式:使用變數儲存定時器 ID,啟動前檢查是否已存在
  3. 清理機制:提供停止函數,在元件銷毀、頁面卸載時呼叫 clearInterval
  4. 優先使用 setInterval:需週期性執行時,直接用 setInterval 而非 setTimeout 遞迴

進階:使用 requestAnimationFrame 實現平滑動畫

若涉及視覺動畫(如顏色漸變),建議改用 requestAnimationFrame:

let animationId = null;
function animateColor() {
    // 計算插值顏色...
    animationId = requestAnimationFrame(animateColor);
}
function stopAnimation() {
    cancelAnimationFrame(animationId);
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved