iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0
JavaScript

JS 核心重構:勇者轉職傳說系列 第 18

Day 17:時間管理大師:Timeout 與 Interval 的實作應用

  • 分享至 

  • xImage
  •  

本文同步分享於個人部落格:Liwen Chiou | Digital Architect & Full-Stack Engineer


📜 這裡的修煉規則:

孩子,在踏上今日的領地前,先坐下來喝杯酒吧。
修煉的路很長,別急著奔跑,先聽聽這份卷軸裡的古老叮嚀。

我在每一站的盡頭都為你鋪設了 實戰演武場 CodePen。那不只是程式碼的拼湊,而是你在這場暴風雨中,試圖用邏輯點燃的一顆星火。
成功突圍後,別忘了帶著你的戰利品回到 QuestBoard 佈告欄。在那裡,你會發現自己從不孤單,公會的夥伴們都正舉杯等待你的歸來。

記住...

導師看重的從來不是你的劍法有多華麗,而是當你被邏輯擊潰、滿身泥濘後,依然選擇握緊理性的劍柄,再次向真相發起衝鋒的勇氣。


🛡️ 【公會大廳:導師的修煉導讀】

「導師,為什麼這顆定時炸彈明明就在我眼前,但我卻沒辦法在它爆炸前把它拆掉?我明明知道它 3 秒後會爆啊!」

我遞給新手冒險者一個刻著數字的銅牌說:「孩子,要在廣大的地圖中拆除陷阱,你不能只是對著空氣喊停。你必須在埋下陷阱的那一刻,接住那枚『計時標籤 (Timer ID)』。唯有手握標籤,你才有權力對瀏覽器下令:『解除這場危機。』」

今天,我們要學習如何成為時間的操縱者。不管是定時觸發的陷阱,還是持續扣血的劇毒,只要掌握了 ID,你就是時間的管理大師。


💡 【導師講義:底層真相探究】

1. 兩大時間咒語:Timeout vs. Interval

在 JS 的時空裡,處理時間只有這兩招:

  • setTimeout(function, delay)延遲爆發。就像定時炸彈,數到 0 就炸,只炸一次。
  • setInterval(function, delay)循環觸發。就像中毒狀態,每隔一段時間就扣一次血,直到死亡(或被解除)為止。

🏹 導師的辨析:時間標籤 (Timer ID)

當你呼叫 set 系列指令時,它會回傳一個整數 ID。如果你不接住這個 ID,你就永遠無法停止計時。

特性 setTimeout setInterval
觸發次數 只有一次 持續循環
清除指令 clearTimeout(id) clearInterval(id)

2. 安全拆彈術:有開就要有關

這是職人開發者與新手的最大分水嶺。如果你的計時器只是不斷開啟卻從不關閉,瀏覽器的記憶體就會像溢出的木桶一樣,最終導致程式崩潰。

// 1. 埋下炸彈,並接住它的標籤 ID
const bombId = setTimeout(() => {
  console.log("💥 爆炸了!");
}, 3000);

// 2. 在爆炸前及時拆除
btn.addEventListener("click", () => {
  clearTimeout(bombId);
  console.log("🛡️ 危機解除。");
});

3. 本日圖解心法:時鐘代管員

導師的圖解心法: 想像 JavaScript 是個單手辦事員。當他遇到計時任務時,他並不會「停下來等」,而是把任務交給旁邊的 「瀏覽器管理員」,並領取一張 標籤 (ID)。管理員會幫你盯著時鐘,時間一到,才把任務塞回辦事員的待辦清單中。

計時器原理圖


⚔️ 【戰術對抗:學長與學弟的代碼對決】

招式示範:技能 CD 冷卻系統

❌ 冒險學弟:無限連發,破壞平衡

  • 負能量評級:🔴 邏輯漏洞 / 🔴 回饋反應極差
btn.addEventListener("click", () => {
  castSpell(); // 點一下發一招,點一百下變核彈
});

✅ 勇者學長:精確管理冷卻時間

  • 利潤評級:🟢 遊戲平衡 / 🟢 防呆機制完美
let isCooldown = false;

btn.addEventListener("click", () => {
  if (isCooldown) return; // 冷卻中,禁止施放

  isCooldown = true;
  castSpell();
  btn.disabled = true;

  // 5 秒後解除冷卻
  setTimeout(() => {
    isCooldown = false;
    btn.disabled = false;
    console.log("✨ 技能已冷卻完成!");
  }, 5000);
});

🏰 【勇者精英課:邁向職人的進階架構】

setTimeout(0) 的神祕時差

你有沒有試過寫 setTimeout(..., 0)?你可能會以為它會「立刻執行」。
但真相是:即便延遲是 0,它依然必須先進入 「非同步排隊區」。JavaScript 會先忙完手頭上所有的「同步任務」,才回頭看這些排隊的計畫。這就是為什麼有時候我們會用這招來「打斷現有的執行順序」,讓某些事情稍後再發生。


🛖 【營火叮嚀:導師的經驗談】

孩子,導師當年最慘的錯誤就是忘記清除 setInterval
我寫了一個自動儲存系統,結果每重整一次畫面,計時器就多累積一個。最後我的帳本每秒被寫入一百次,整個公會的資料庫差點被我癱瘓。

記住:任何時候只要你決定啟動循環 (Interval),心中就必須先想好在哪裡要關掉它。

💡 悄悄話: 在明天的 Day 18 期中佈告欄實戰 中,我們就會用到這招,讓「儲存成功」的提示視窗在顯示 3 秒後自動消失喔!


天色微亮,營火雖已燃盡,但你眼中卻閃爍著領悟的光芒。在前往演武場挑戰關卡前,我已經幫你把靈魂碎片精煉成了這份「戰術錦囊」。拿好它,今日的任務不再是負擔,而是你證明自我的舞台。去吧,公會的英雄榜在等著你的戰報。

📝 【夥伴筆記:今日修煉精華】

  • setTimeout:單次預約,時間到執行。
  • setInterval:循環固定周期,需手動終止。
  • Clear 系列:拆彈指令,必須配合 Timer ID 使用。
  • 非同步自覺:計時器不會阻塞代碼運行。

🎯 【實戰演武場】

⚔️ 任務鑑定條件:

  1. 完成 📜 本日實戰任務 (CodePen)
  2. 將 CodePen 網址貼至 QuestBoard,並回填鑑定報告:
    • 初心者:定時炸彈拆除 (成就感發掘)
        1. 你是否成功接住 Timer ID 並在它爆炸前將其 clear 掉?
    • 冒險者:循環的噩夢 (理性挑戰)[⚡ 觀念辨析]
        1. 如果你沒關掉 setInterval 就跳轉頁面,計時器會發生什麼事?(雖然暫時看不到,但它還在後台偷跑嗎?)

📚 【圖書館卷軸:延伸學習】


上一篇
Day 16:瀏覽器小帳本:幫使用者存下他的個人設定(LocalStorage)
下一篇
Day 18:【期中實戰】純 JS 打造你的第一個「任務佈告欄」
系列文
JS 核心重構:勇者轉職傳說19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言