Promise.all 之購物車案例

2 min

閱讀範圍

🛒 Promise.all 在購物車的魔法應用(從入門到進階)

作者的觀點 or 知識點

  • Promise.all 一次並行執行多個非同步任務,等所有任務都完成後,再一次返回結果。

  • Promise.all 透過並行處理無相依性的 request 請求,可以有效提升速度

方法適用場景
Promise.all小量請求(<1000)
Promise.allSettled允許部分請求失敗
批次處理API 過載風險
並發控制 (p-limit)保持穩定請求數
延遲請求 (setTimeout)API Rate Limit 限制

作者的舉例

加速購物車載入

async function loadCart() {
  try {
    const [user, cartItems, coupons] = await Promise.all([fetchUser(), fetchCartItems(), fetchCoupons()])

    console.log('👤 使用者資料:', user)
    console.log('🛒 購物車商品:', cartItems)
    console.log('🎟️ 可用優惠券:', coupons)
  }
  catch (error) {
    console.error('❌ 載入失敗:', error)
  }
}

BUT!!!!!
這種情況會可能會遇到其中一個 API 爆掉就直接整個網頁 crash, 所以可以考慮使用 Promise.allSettled

大量的資料請求

  1. 批次處理
async function batchRequests(items, batchSize = 100) {
  const results = []

  for (let i = 0; i < items.length; i += batchSize) {
    const batch = items.slice(i, i + batchSize)
    console.log(`🚀 執行批次 ${i / batchSize + 1}`)

    const batchResults = await Promise.all(batch.map(item => fetchProductDetails(item.id)))
    results.push(...batchResults)
  }

  return results
}
  1. 限制最大併發數量
import pLimit from 'p-limit'

async function fetchAllProducts(items, concurrency = 100) {
  const limit = pLimit(concurrency)
  const tasks = items.map(item => limit(() => fetchProductDetails(item.id)))
  return Promise.all(tasks)
}
  1. setTimeout 控制 API Rate Limit
async function fetchWithDelay(items, delay = 100) {
  const results = []

  for (let i = 0; i < items.length; i++) {
    await new Promise(resolve => setTimeout(resolve, delay))

    try {
      const result = await fetchProductDetails(items[i].id)
      results.push(result)
      console.log(`✅ ${i + 1}/${items.length} 完成`)
    }
    catch (error) {
      console.error(`❌ 第 ${i + 1} 筆請求失敗:`, error)
    }
  }

  return results
}

試著用一段簡短文字描述此次閱讀的內容

作者透過 Promise.all 來解決購物車會遇到的實際場景,並且針對其缺點也有附上 Promise.allSettled 的解決方式,加上並行請求實實在在的可以改善使用者進入網頁後的體驗。