跳至主要内容

Promise.all 之購物車案例

閱讀範圍

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