Promise.all 之購物車案例

閱讀範圍

作者的觀點 or 知識點

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

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

方法適用場景
Promise.all小量請求(<1000)
Promise.allSettled.md允許部分請求失敗
批次處理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.md

大量的資料請求

  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.md 的解決方式,加上並行請求實實在在的可以改善使用者進入網頁後的體驗。