Với dashboard, câu trả lời gần như luôn là Promise.allSettled: mỗi widget hiển thị độc lập, một API lỗi không nên xoá trắng cả trang.
js
const results = await Promise.allSettled([getStats(), getOrders(), getFeed()])
results.forEach((r) => {
if (r.status === 'fulfilled') render(r.value)
else renderErrorCard(r.reason)
})Chọn theo ngữ nghĩa:
all— fail-fast, reject ngay khi một cái lỗi. Dùng khi thiếu bất kỳ mảnh nào thì kết quả vô nghĩa (vd cần cả user + permission mới render được trang).allSettled— không bao giờ reject, luôn trả mảng{ status, value | reason }khi tất cả đã xong. Dùng cho dữ liệu độc lập, cho batch job cần biết cái nào hỏng.race— settle theo cái xong trước, kể cả khi nó reject. Dùng để ghép timeout:Promise.race([fetchData(), timeout(3000)]).any— trả về cái fulfilled đầu tiên, bỏ qua các reject; chỉ reject khi tất cả hỏng (AggregateError). Dùng khi có nhiều nguồn tương đương (mirror, CDN dự phòng).
Bẫy hay bị hỏi thêm: all reject không huỷ các promise còn lại — chúng vẫn chạy tới cùng, và nếu cái khác cũng reject thì đó là rejection không ai bắt. Muốn dừng thật sự phải truyền AbortSignal chung.