Promise Nâng Cao: all, allSettled, race, any — Khi Nào Dùng Cái Nào?
Nếu bạn chỉ dùng async/await tuần tự, ứng dụng của bạn đang bỏ phí tiềm năng hiệu suất — mỗi request phải chờ request trước xong mới bắt đầu. Các phương thức tĩnh của Promise (all, allSettled, race, any) cho phép bạn điều phối nhiều tác vụ bất đồng bộ song song theo chiến lược phù hợp từng bài toán.

Trung Vũ Hoàng
Tác giả
1. Promise.all — "Tất Cả Hoặc Không Có Gì"
Thực thi tất cả Promise cùng lúc và chờ đến khi mọi Promise thành công. Nếu bất kỳ một Promise nào thất bại, toàn bộ thất bại ngay lập tức.
const [userData, posts] = await Promise.all([
fetch('/api/user').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
]);Dùng khi:
Dashboard cần tải nhiều dữ liệu phụ thuộc lẫn nhau.
Truy vấn database song song để giảm thời gian phản hồi API.
Kiểm tra nhiều file trước khi upload.
Chú ý: Nếu một request thất bại, bạn không biết các request khác kết quả gì. Với tình huống cần biết từng kết quả riêng — dùng allSettled.
2. Promise.allSettled — "Chờ Hết, Không Bỏ Ai"
Chờ tất cả Promise kết thúc — thành công hay thất bại đều được. Kết quả trả về là mảng các object chứa status và value/reason. (ES2020)
const results = await Promise.allSettled([
sendEmail(user1),
sendEmail(user2),
sendEmail(user3)
]);
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log('Gửi thành công:', result.value);
} else {
console.error('Gửi lỗi:', result.reason);
}
});Dùng khi:
Gửi email hàng loạt — cần biết email nào thành công, email nào lỗi.
Xóa nhiều record — tiếp tục dù một vài record lỗi phân quyền.
Tổng hợp data từ nhiều third-party API không ổn định.
3. Promise.race — "Ai Về Đích Trước Thì Thắng"
Trả về kết quả của Promise hoàn thành đầu tiên — dù là thành công hay thất bại. Phần còn lại bị bỏ qua.
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error('Request timeout!')), 5000)
);
const data = await Promise.race([
fetch('/api/slow-endpoint'),
timeout
]);Dùng khi:
Cài timeout cho request đến server chậm.
Lấy data từ nhiều server mirror — chọn server phản hồi nhanh nhất.
Hủy animation nếu sự kiện người dùng xảy ra trước.
4. Promise.any — "Chỉ Cần Một Cái Thành Công"
Trả về kết quả của Promise thành công đầu tiên. Bỏ qua các Promise thất bại. Chỉ fail nếu tất cả Promise đều thất bại — lúc đó ném ra AggregateError chứa mọi lý do lỗi. (ES2021)
const image = await Promise.any([
loadFromCDN_A(imageUrl),
loadFromCDN_B(imageUrl),
loadFromCDN_C(imageUrl)
]);Dùng khi:
Load ảnh từ nhiều CDN — đảm bảo ảnh luôn hiển thị dù một CDN sập.
Xác thực qua nhiều gateway song song.
Truy vấn từ cache và network cùng lúc — lấy cái nào có data trước.
5. Tổng Hợp: Chọn Phương Thức Nào?
Phương thức | Resolve khi | Reject khi | Dùng cho |
|---|---|---|---|
| Tất cả thành công | Một thất bại | Dữ liệu phụ thuộc nhau |
| Tất cả hoàn tất | Không bao giờ | Cần biết mọi kết quả |
| Một hoàn tất (bất kỳ) | Một thất bại (bất kỳ) | Timeout, server race |
| Một thành công | Tất cả thất bại | Fallback, multi-source |
6. Những Lưu Ý Quan Trọng
Luôn có
.catch(): Promise không xử lý lỗi sẽ crash Node.js process hoàn toàn.Giới hạn số request song song:
Promise.allvới 100 request cùng lúc có thể nghẽn băng thông — cân nhắc chia batch.Kiểm tra Browser Compatibility:
Promise.anyvàallSettledchưa hỗ trợ trên IE và một số browser cũ.
Tổng Kết
Bốn phương thức tĩnh của Promise phục vụ bốn chiến lược điều phối hoàn toàn khác nhau. Chọn đúng phương thức không chỉ làm code sạch hơn mà còn tránh được các lỗi logic tinh vi:
all→ Cần tất cả, không chấp nhận thiếu sót.allSettled→ Cần biết kết quả từng phần, kể cả lỗi.race→ Chỉ cần kết quả nhanh nhất, dù tốt hay xấu.any→ Cần ít nhất một thành công, bỏ qua thất bại.
Câu hỏi thường gặp
Bài viết liên quan

Zustand Async: 5 Cách Xử Lý Bất Đồng Bộ Hiệu Quả Trong React
Mọi ứng dụng React thực tế đều phải giao tiếp với API bất đồng bộ. Nếu quản lý kém, ứng dụng dễ rơi vào các vấn đề như UI bị đơ, race condition, rò rỉ bộ nhớ, hay hiển thị dữ liệu cũ. Zustand giải quyết bài toán này với một cú pháp cực kỳ đơn giản — định nghĩa async actions trực tiếp trong store, không cần middleware phức tạp như Redux Thunk hay Saga.

Zustand Async: 5 Cách Xử Lý Bất Đồng Bộ Hiệu Quả Trong React
Mọi ứng dụng React thực tế đều phải giao tiếp với API bất đồng bộ. Nếu quản lý kém, ứng dụng dễ rơi vào các vấn đề như UI bị đơ, race condition, rò rỉ bộ nhớ, hay hiển thị dữ liệu cũ. Zustand giải quyết bài toán này với một cú pháp cực kỳ đơn giản — định nghĩa async actions trực tiếp trong store, không cần middleware phức tạp như Redux Thunk hay Saga.

Virtualization Trong React: Kỹ Thuật Xử Lý 100.000 Dòng Dữ Liệu Không Giật Lag
Bạn có một danh sách 50.000 dòng cần hiển thị trong React. Nếu render tất cả cùng lúc, trình duyệt sẽ phải dựng hàng chục nghìn DOM node — CPU và RAM rên rỉ, UI giật lag nghiêm trọng, và điểm Core Web Vitals lao dốc. Virtualization (hay Windowing) giải quyết bài toán này bằng một nguyên lý đơn giản mà cực kỳ hiệu quả.