Promise 和 setTimeout 的深入解析

在 JavaScript 中,Promise 和 setTimeout 是處理非同步操作的兩個重要工具。雖然它們都用於處理非同步事件,但它們的工作方式和使用場景有所不同。讓我們深入探討這兩個概念。

Promise

Promise 是 JavaScript 中用於處理非同步操作的對象。它代表了一個可能尚未完成的操作,但在未來的某個時間點會完成。Promise 有三種狀態:

  1. Pending(進行中):初始狀態,既未完成也未拒絕。
  2. Fulfilled(已完成):操作成功完成。
  3. Rejected(已拒絕):操作失敗。

Promise 的優點包括:

  • 可以將非同步操作以同步操作的流程表達出來,避免了回調地獄。
  • 提供了 .then().catch().finally() 方法,使得處理非同步操作的結果更加直觀。

Promise 的基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const myPromise = new Promise((resolve, reject) => {
// 非同步操作
if (/* 操作成功 */) {
resolve(result);
} else {
reject(error);
}
});

myPromise.then(result => {
// 處理成功的結果
}).catch(error => {
// 處理錯誤
});

setTimeout

setTimeout 是一個全局函數,用於在指定的毫秒數後執行一段代碼。它是 JavaScript 非同步編程的基礎之一。

setTimeout 的基本語法如下:

1
setTimeout(callback, delay);

其中,callback 是要執行的函數,delay 是延遲的毫秒數。

setTimeout 的特性

  1. 非阻塞:setTimeout 不會阻塞代碼的執行。它會將回調函數加入到事件佇列中,等待執行。
  2. 最小延遲:即使設置延遲為 0,回調函數也不會立即執行。它會在當前執行棧清空後才執行。
  3. 計時器精度:由於 JavaScript 的單執行緒特性和事件循環機制,setTimeout 的實際延遲可能會比指定的時間長。

Promise 和 setTimeout 的結合使用

Promise 和 setTimeout 可以結合使用,創建一個在指定時間後解決的 Promise:

1
2
3
4
5
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

delay(2000).then(() => console.log('2 秒後執行'));

事件循環和執行順序

理解 Promise 和 setTimeout 的執行順序,需要了解 JavaScript 的事件循環機制:

  1. 同步代碼優先執行。
  2. 微任務(如 Promise 的 then/catch/finally)在當前任務結束後立即執行。
  3. 宏任務(如 setTimeout、setInterval)在下一次事件循環中執行。

以下面的代碼為例:

1
2
3
4
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');

輸出順序將會是:1, 4, 3, 2

這是因為:

  • '1' 和 '4' 是同步代碼,立即執行。
  • Promise.then 是微任務,在同步代碼執行完後立即執行。
  • setTimeout 是宏任務,在下一次事件循環中執行。

結論

Promise 和 setTimeout 都是處理 JavaScript 非同步操作的重要工具。Promise 提供了更強大和靈活的方式來處理非同步操作的結果,而 setTimeout 則用於延遲執行代碼。理解這兩個概念以及它們在事件循環中的行為,對於編寫高效且可靠的 JavaScript 代碼至關重要。