2024-11-14 為什麼碼錶程式 要用到 setInterval() ? 它並沒有時間的概念

2024-11-14 為什麼碼錶程式 要用到 setInterval() ? 它並沒有時間的概念

所以為什麼碼錶程式 要用到 setInterval() ? 它並沒有時間的概念

碼錶程式需要用到 setInterval() 的原因,雖然它本身並不處理「時間的概念」,但它依賴的是 setInterval() 提供的「週期性執行能力」,來模擬碼錶的計時功能。讓我們一步步解析原因。


1. setInterval() 的核心功能

  • setInterval() 的作用是 每隔一定的時間執行一次指定的操作
  • 在碼錶程式中,我們需要每隔一段時間(例如 10 毫秒)更新碼錶的數值,使畫面上的數字看起來像是在「計時」。

2. 為什麼碼錶需要更新顯示?

碼錶程式的主要功能是:

  1. 展示經過的時間
  2. 不斷刷新顯示,讓人看到時間在變化。

如果沒有 setInterval()

  • 無法讓顯示的數值自動更新。
  • 用戶就無法看到時間的流逝。

3. 模擬碼錶的例子

沒有 setInterval() 的情況

如果不使用 setInterval() 或類似的方式,碼錶的數值必須手動更新:

1
2
3
4
5
6
7
8
9
let time = 0;
function updateManually() {
time += 10; // 每次手動增加時間
console.log(time);
}
// 需要用戶手動執行
updateManually();
updateManually();
// 時間並不會自動更新

這樣碼錶就無法持續顯示變化,用戶體驗會很差。


使用 setInterval() 模擬碼錶

使用 setInterval() 的碼錶程式如下:

1
2
3
4
5
6
let time = 0;
const timer = setInterval(() => {
time += 10; // 每隔 10 毫秒增加 10
console.log(time); // 顯示當前時間
if (time >= 1000) clearInterval(timer); // 假設停止在 1 秒
}, 10);

結果:

  • 程式會自動在每 10 毫秒執行一次時間更新,直到停止為止。
  • 這讓碼錶看起來像是在「計時」。

4. 碼錶程式的需求分析

  • 時間持續增加:碼錶需要模擬「經過的時間」。
    • 解決方法:將每次間隔的時間(如 10 毫秒)加到總時間 time 中。
  • 畫面自動更新:用戶希望看到「動態的時間」。
    • 解決方法:使用 setInterval() 讓時間持續刷新。

5. 碼錶程式用到 setInterval() 的具體用途

在 Vue 的碼錶程式中,setInterval() 的用途主要是:

  1. **更新數據 (this.time)**:

    • 程式碼:this.time += 10;
    • 每 10 毫秒執行一次,使時間數據不斷增加。
  2. 觸發 Vue 的響應式更新

    • 透過 Vue 的響應式系統,當 this.time 改變時,自動觸發畫面更新,顯示最新時間。

6. 如果不用 setInterval(),可以用什麼?

雖然 setInterval() 是實現碼錶的常用方式,但也可以考慮以下替代方案:

  1. **setTimeout()**:

    • 每次執行後再次設定下一次執行,這樣可以更精確地控制執行時間:
      1
      2
      3
      4
      5
      6
      function runTimer() {
      this.time += 10;
      console.log(this.time);
      setTimeout(runTimer, 10); // 設定下一次執行
      }
      runTimer();
  2. 動畫框架

    • 使用瀏覽器的 requestAnimationFrame() 來計時並刷新畫面(更適合需要高效的動畫場景)。

7. 總結

setInterval() 在碼錶程式中是不可或缺的,因為它提供了:

  • 週期性更新數據的能力
  • 模擬碼錶功能的基礎工具
  • 觸發 Vue 的響應式更新,讓畫面自動同步時間的變化

如果沒有 setInterval(),碼錶就無法自動計時,用戶也無法即時看到時間的變化,失去使用碼錶的意義。

requestAnimationFrame() 這是 javascript 的原生函式?

是的,requestAnimationFrame()JavaScript 的原生函式,由瀏覽器提供,用於執行高效的動畫或畫面刷新操作。它是專門設計來取代傳統的 setInterval()setTimeout() 進行動畫更新的,提供了更好的性能和流暢度。


1. requestAnimationFrame() 是什麼?

requestAnimationFrame() 的作用是:

  • 告訴瀏覽器:在下一次屏幕重繪之前執行一段指定的函式。
  • 瀏覽器會根據屏幕的刷新率(通常是每秒 60 次,等於 16.66 毫秒一次)來調整執行頻率,確保動畫更新的效率和流暢性。

2. 語法

1
let requestID = requestAnimationFrame(callback);

參數

  • callback: 你想要執行的函式,會在每次屏幕重繪時被調用。

返回值

  • requestID: 一個數字標識符,用於取消這次動畫請求(配合 cancelAnimationFrame())。

3. 簡單範例

以下是一個使用 requestAnimationFrame() 實現簡單動畫的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
let start = null;

function step(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;

console.log(progress); // 每次刷新時輸出經過的時間
if (progress < 2000) { // 動畫持續 2 秒
requestAnimationFrame(step);
}
}

requestAnimationFrame(step);

解釋:

  1. timestamp: 由瀏覽器傳入,表示從頁面加載到現在的時間(以毫秒為單位)。
  2. step 函式中,我們計算時間進度 progress,並根據進度執行動畫邏輯。

4. requestAnimationFrame() 的優勢

相比於 setInterval()setTimeout()requestAnimationFrame() 的優勢如下:

1. 同步屏幕刷新率

  • requestAnimationFrame() 自動根據屏幕刷新率調整執行頻率,通常每秒 60 次(約 16.66 毫秒一次),可以保證動畫的流暢性。

2. 節省資源

  • 在頁面不可見或不活動時(比如切換到其他標籤頁),瀏覽器會暫停動畫執行,減少不必要的資源消耗。

3. 更精確的時間間隔

  • requestAnimationFrame() 的執行時機比 setInterval() 更準確,因為它直接集成到瀏覽器的重繪機制中。

4. 避免卡頓

  • 使用 requestAnimationFrame() 可以減少掉幀的情況,讓動畫更平滑。

5. 在碼錶中使用 requestAnimationFrame()

如果你想用 requestAnimationFrame() 來實現碼錶功能,可以這樣做:

碼錶範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let start = null;
let elapsed = 0; // 經過的時間

function updateTimer(timestamp) {
if (!start) start = timestamp;
elapsed = timestamp - start;

console.log(Math.floor(elapsed)); // 輸出經過的時間(毫秒)

if (elapsed < 10000) { // 計時到 10 秒為止
requestAnimationFrame(updateTimer);
}
}

requestAnimationFrame(updateTimer);

對應的 Vue 實現

在 Vue 中,可以這樣整合 requestAnimationFrame()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
export default {
data() {
return {
time: 0,
startTime: null,
timerID: null,
};
},
methods: {
startTimer() {
const updateTime = (timestamp) => {
if (!this.startTime) this.startTime = timestamp;
this.time = Math.floor(timestamp - this.startTime);

// 繼續請求下一幀
this.timerID = requestAnimationFrame(updateTime);
};

this.timerID = requestAnimationFrame(updateTime);
},
stopTimer() {
cancelAnimationFrame(this.timerID); // 停止動畫
this.timerID = null;
},
resetTimer() {
this.stopTimer();
this.time = 0;
this.startTime = null;
},
},
};

6. 總結

requestAnimationFrame() 是 JavaScript 原生的高效動畫工具,適合用於實現:

  • 動畫
  • 動態數字變化
  • 時間計算等

在碼錶中,它可以作為 setInterval() 的替代方案,提供更加流暢和高效的更新機制。