Một dashboard tải số đơn hàng và thông báo từ hai nguồn độc lập. Nếu nguồn thông báo lỗi, người dùng vẫn có thể cần xem số đơn hàng. Promise.allSettled giúp thu thập kết quả của từng tác vụ, nhưng ứng dụng phải chủ động quyết định phần nào được hiển thị và phần nào cần báo lỗi.
1. Chờ kết quả, không biến thất bại thành thành công
Theo tài liệu Promise.allSettled của MDN, phương thức chờ các promise đầu vào kết thúc ở trạng thái fulfilled hoặc rejected, rồi trả danh sách kết quả theo thứ tự đầu vào. Với mỗi mục, đọc value khi fulfilled và reason khi rejected.
Việc promise tổng hợp fulfilled không có nghĩa mọi tác vụ đều thành công. Đây là điểm dễ gây lỗi nếu mã chỉ await rồi hiện thông báo “Đã tải toàn bộ dữ liệu”.
2. Ví dụ không gọi API thật
async function demoDashboard() {
const jobs = [
{ key: 'orders', run: () => Promise.resolve({ count: 12 }) },
{ key: 'notices', run: () => Promise.reject(new Error('Unavailable')) }
];
const results = await Promise.allSettled(
jobs.map(job => Promise.resolve().then(job.run))
);
return results.map((result, index) => ({
key: jobs[index].key,
status: result.status,
...(result.status === 'fulfilled'
? { data: result.value }
: { message: 'This section could not be loaded' })
}));
}
demoDashboard().then(console.log);
Kết quả mong đợi gồm orders thành công với count bằng 12 và notices thất bại với thông báo đã kiểm soát. Promise.resolve().then(job.run) còn chuyển lỗi ném đồng bộ trong hàm run thành rejection để được tổng hợp. Ví dụ không gửi request, không ghi dữ liệu và không phải benchmark.
3. Giữ định danh khi ghép kết quả
Mảng results tương ứng vị trí với jobs, không phải thứ tự tác vụ hoàn thành. Gắn key giúp giao diện biết kết quả thuộc ô nào. Không sắp xếp hoặc thay đổi jobs trong lúc đang chờ rồi dùng index của danh sách mới để ghép lại.
Ở ô lỗi, hãy hiển thị trạng thái “Không tải được” thay vì số 0. Không có dữ liệu vì request thất bại khác với kết quả thật là không có đơn hàng hay không có thông báo.
4. Những việc allSettled không tự làm
- Không đặt timeout: một promise mãi pending có thể làm cả lần chờ kéo dài.
- Không giới hạn số tác vụ chạy đồng thời; khởi tạo hàng nghìn request vẫn có thể gây quá tải.
- Không tự retry, hủy request hoặc hoàn tác tác dụng phụ.
- Không kiểm tra HTTP status: khi dùng fetch, phải kiểm tra response.ok theo hợp đồng API.
Nếu cần hiển thị từng ô ngay khi xong, không nên chỉ chờ kết quả tổng hợp rồi mới cập nhật tất cả. Hãy thiết kế trạng thái riêng cho từng vùng và dùng kết quả tổng hợp khi cần báo cáo cuối cùng.
5. Chọn theo nghiệp vụ
allSettled phù hợp khi các phần việc độc lập và kết quả một phần vẫn hữu ích. Với luồng cần mọi dữ liệu để tiếp tục, Promise.all có thể phù hợp hơn, nhưng nó cũng không tự hủy các tác vụ còn lại khi một promise reject.
Không coi bất kỳ phương thức Promise nào là transaction. Nếu nhiều tác vụ cùng ghi dữ liệu, tính nhất quán và phục hồi khi lỗi phải được thiết kế ở lớp nghiệp vụ hoặc hệ thống lưu trữ.
6. Checklist kiểm thử
- Tất cả thành công, một tác vụ lỗi và tất cả lỗi.
- Tác vụ hoàn thành khác thứ tự đầu vào.
- Hàm tác vụ ném lỗi đồng bộ.
- Một tác vụ chậm hoặc không kết thúc.
- Giao diện không dùng dữ liệu giả thay cho lỗi.
- Thông báo công khai không lộ chi tiết nội bộ từ reason.
Promise.allSettled hữu ích khi cần nhìn đầy đủ kết quả của nhiều tác vụ. Giá trị thực tế nằm ở cách ứng dụng diễn giải từng kết quả, không chỉ ở việc tránh một exception tổng hợp.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.