---
# System prepended metadata

title: Promise.race 實作
tags: [Promise, 筆記, JavaScript]

---

## Promise.race 實作
`Promise.race` 是 JavaScript 提供的一個方法，用於競賽多個 Promise，並返回第一個完成（無論是解決還是拒絕）的 Promise 的結果。這意味著，無論哪個 Promise 最先完成，`Promise.race` 都會使用該 Promise 的結果來解決或拒絕它返回的新 Promise。

Promise.race 的實現原理也和事件循環（Event Loop）的工作機制緊密相關。以下是運作過程及其在事件循環中的各個階段。

### Promise.race 的實現原理
1. 創建外層 Promise：
    * Promise.race 返回一個新的外層 Promise，這個 Promise 的狀態由傳入的 promiseArray 陣列中的任意一個 Promise 首先被解析（fulfilled）或拒絕（rejected）來決定。
1. 遍歷 promiseArray 陣列：
    * 逐個遍歷傳入的 Promise，並為每個 Promise 註冊 then 和 catch 處理器。
    * 當任意一個 Promise 被觸發時，對應的處理器會被推入微任務佇列（Microtask Queue）。
1. 處理微任務：
    * 事件循環首先執行堆疊中的同步代碼，然後處理微任務佇列中的回調函式。
    * 最早被觸發的 Promise 的回調函式最先被執行，外層 Promise 的狀態立即被決定。
1. 輸出結果：
    * 當最早的 Promise 解析或拒絕後，外層 Promise 在跟著一起對應結果或錯誤被返回。
    * 隨後的 Promise 的狀態不再影響外層的結果。

poo-poo code
```javascript!
const promiseArray = [
  new Promise((resolve) => setTimeout(() => resolve('First'), 500)),
  new Promise((resolve) => setTimeout(() => resolve('Second'), 100)),
  new Promise((resolve) => setTimeout(() => resolve('Third'), 300))
];

const race = (items) => {
    return new Promise((resolve, reject) => {
      items.forEach(item=> {
          item
              .then(res=> resolve(item))
              .catch(e=> reject(e))
      })
    })
}

console.log(await race(promiseArray))
```

> 在這個例子中，最先被解析的 Promise 是第二個（100 毫秒後），因此返回的結果是 "Second"。事件循環確保最先被解析的 Promise 的回調函式最早被執行。

### 事件循環的作用
* 堆疊（Call Stack）： 同步代碼逐行執行，調用的函式壓入堆疊，執行完後彈出。
* 微任務佇列（Microtask Queue）： 包含 Promise 的回調中，微任務在每個堆疊清空後立即執行，優先於宏任務。
* 宏任務佇列（Macrotask Queue）： 包含 setTimeout 等回調。宏任務在所有微任務執行完後執行。


### 總結
> 所以簡單來說其實 Promise.race 只是在 promiseArray 外再包了一層 promise，等誰是最快的回傳而已。

* Promise.race 返回最早被解析或拒絕的 Promise 的結果。
* 事件循環在處理微任務時優先於宏任務，保證了回調函式的執行順序。
* Promise.race 通過遍歷 promiseArray 陣列並註冊回調函式，實現了比賽機制，最先完成的 Promise 決定了比賽的結果。
* 通過理解 Promise.race 與事件循環的交互過程，我們能更好地掌握 JavaScript 中的非同步操作和回調機制。