JavaScript 定時器:setTimeout 與 setInterval 用法
以下 Away 就用 JavaScript 讓您使用瀏覽器內建的計時器。它們屬於 Web API 的一員,負責讓程式碼 延遲執行 或 定時重複。
setInterval()
用於按指定的時間間隔重複執行函式。
js
setInterval(handler, duration);參數
| 功能 | 說明 | 型別 | 範例 | 備註 |
|---|---|---|---|---|
| handler | 執行事項 | Function | function() {} | 必填 |
| duration | 間隔時間(毫秒) | Number | 400 | 必填 |
js
// 每秒印出一次現在時間
const intervalID = setInterval(() => {
console.log(new Date().toLocaleTimeString());
}, 1000);clearInterval()
用於清除定時函式。
js
clearInterval(intervalID);參數
| 功能 | 說明 | 型別 | 範例 | 備註 |
|---|---|---|---|---|
| intervalID | 清除的對象 | Number | intervalID | 必填 |
注意
setInterval() 會回傳一個 ID,一定要先存起來,否則之後沒有辦法清除它。沒清掉的定時器會一直跑,造成不必要的運算與記憶體洩漏。
setTimeout()
用於在指定的延遲時間後執行一次函式。
js
setTimeout(handler, duration);參數
| 功能 | 說明 | 型別 | 範例 | 備註 |
|---|---|---|---|---|
| handler | 執行事項 | Function | function() {} | 必填 |
| duration | 延遲時間(毫秒) | Number | 400 | 必填 |
js
// 3 秒後把提示訊息關掉
const timerID = setTimeout(() => {
document.querySelector('#Msg').classList.remove('is-show');
}, 3000);clearTimeout()
用於清除延遲函式。
js
clearTimeout(timerID);參數
| 功能 | 說明 | 型別 | 範例 | 備註 |
|---|---|---|---|---|
| timerID | 清除的對象 | Number | timerID | 必填 |
兩者的差別
| 方法 | 執行次數 | 清除用 |
|---|---|---|
setTimeout() | 一次 | clearTimeout() |
setInterval() | 重複,直到被清除 | clearInterval() |
小提醒
延遲時間是 最短等待時間,不是精準時間。JavaScript 是單執行緒,時間到了還得等主執行緒空下來才會執行,所以前面有耗時運算時會被往後推。
實務上最常用的兩招
去彈跳(debounce)
使用者 停手之後 才執行一次,適合搜尋框的即時查詢:
js
let timerID = null;
document.querySelector('#InputText').addEventListener('input', (e) => {
clearTimeout(timerID);
timerID = setTimeout(() => {
console.log('開始搜尋:', e.target.value);
}, 500);
});節流(throttle)
固定頻率執行,適合 捲動與視窗事件 這類高頻事件:
js
let isWaiting = false;
window.addEventListener('scroll', () => {
if (isWaiting) return;
isWaiting = true;
console.log(window.scrollY);
setTimeout(() => {
isWaiting = false;
}, 200);
});注意
定時器的回呼裡若拋出錯誤,外層的 try...catch 接不到,因為那段程式已經在之後的另一輪執行。要處理錯誤,請寫在回呼內部。
常見問題
setTimeout 與 setInterval 有什麼差別?
setTimeout() 在延遲時間後只執行一次;setInterval() 會依指定間隔重複執行,直到被 clearInterval() 清除為止。
為什麼一定要清除定時器?
沒有清除的 setInterval() 會一直執行,即使畫面上的元素已被移除,容易造成記憶體洩漏與不必要的運算。離開頁面或關閉元件時請記得清掉。
設定 1000 毫秒就一定剛好 1 秒後執行嗎?
不一定。延遲時間是最短等待時間,實際執行還要等主執行緒空下來。若前面有耗時運算,就會被往後推。
setTimeout 設 0 毫秒是立刻執行嗎?
不是。它會把工作排到目前這一輪程式跑完之後才執行,因此常被用來把工作延到下一輪,讓瀏覽器先完成渲染。
節流與去彈跳差在哪裡?
節流是固定頻率執行,例如:每 200 毫秒最多一次,適合捲動;去彈跳是等使用者停手後才執行一次,適合搜尋框輸入。