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
大量的資料請求
- 批次處理
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;
}- 限制最大併發數量
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);
}- 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 的解決方式,加上並行請求實實在在的可以改善使用者進入網頁後的體驗。