Người dùng chuyển sang màn hình khác khi dữ liệu vẫn đang tải. Ứng dụng không còn cần phản hồi cũ, nhưng request vẫn có thể tiếp tục và cập nhật sai vùng giao diện. AbortController giúp hủy thao tác phía client; điều quan trọng là hiểu giới hạn của nó trước khi áp dụng cho các yêu cầu thay đổi dữ liệu.
1. Kết nối signal với fetch
Theo tài liệu AbortController.abort() của MDN, abort có thể hủy fetch, việc đọc response body hoặc stream liên quan. Controller chỉ hữu ích khi thao tác được kết nối với signal của nó.
Ví dụ sau dành cho trang thử nghiệm có endpoint GET /api/demo-items trả JSON. Nó thực sự gửi request khi chạy; thay endpoint bằng API thử nghiệm được phép sử dụng. Các hàm là khung minh họa, chưa có giao diện nút bấm.
function startLoad() {
const controller = new AbortController();
const task = (async () => {
try {
const response = await fetch('/api/demo-items', {
signal: controller.signal
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
if (!controller.signal.aborted) {
console.log('Loaded', data);
}
} catch (error) {
if (controller.signal.aborted) {
console.log('Cancelled');
return;
}
console.error('Load failed', error);
}
})();
return { cancel: () => controller.abort(), task };
}
const operation = startLoad();
// Call operation.cancel() when the result is no longer needed.
Ví dụ kiểm tra cả HTTP status và lỗi khi đọc JSON. Dữ liệu được in chỉ nên là dữ liệu giả không nhạy cảm; trong ứng dụng thật, thay log bằng cập nhật trạng thái phù hợp và tránh ghi toàn bộ phản hồi vào log production.
2. Tạo controller mới cho lần tải mới
Mỗi lần gọi startLoad tạo một controller riêng. Sau khi đã hủy, không tái sử dụng signal đó cho lần tải tiếp theo. Gắn hàm cancel vào hành động đóng màn hình hoặc vòng đời component theo framework đang dùng.
Hủy quá muộn không xóa kết quả đã được hiển thị. Với ô tìm kiếm gửi nhiều request liên tiếp, còn cần nhận diện lần tìm kiếm hiện tại để phản hồi cũ không ghi đè phản hồi mới. Abort giảm công việc không cần thiết nhưng không thay toàn bộ quy tắc quản lý trạng thái.
3. Hủy ở client không phải hoàn tác ở server
Đây là khác biệt quan trọng với thao tác đặt hàng hoặc cập nhật tài khoản. Khi client ngừng chờ, server có thể đã nhận và xử lý yêu cầu. Không suy ra giao dịch đã thất bại chỉ vì phía trình duyệt báo hủy.
Với tác vụ ghi, cần cơ chế riêng để kiểm tra trạng thái, chống gửi trùng và hủy nghiệp vụ nếu sản phẩm hỗ trợ. Không tự gửi lại thao tác có tác dụng phụ khi chưa biết lần trước đã hoàn thành hay chưa.
4. Không biến mọi lỗi thành “đã hủy”
Thông báo HTTP lỗi, mất mạng và JSON không hợp lệ cần được quan sát riêng. Trong ví dụ, nhánh hủy chỉ được dùng khi signal đã bị hủy; những lỗi khác đi vào nhánh Load failed. Chính sách thông báo thực tế phải xác định người dùng có cần thử lại hay không.
Nếu component đã bị tháo khỏi trang, đừng cập nhật nó trong catch hoặc finally. Các cờ đang tải cũng phải thuộc đúng lần yêu cầu, tránh để lần cũ tắt trạng thái đang tải của lần mới.
5. Checklist thử nghiệm
- GET thành công với JSON hợp lệ.
- Hủy khi server trả chậm và khi body đang được đọc.
- HTTP 500, mất mạng và JSON sai được nhận diện là lỗi thật.
- Lần tải mới dùng controller mới và vẫn hoạt động sau một lần hủy.
- Đóng màn hình không tạo cập nhật giao diện muộn.
- Luồng ghi dữ liệu có bước xác minh trạng thái server độc lập.
AbortController giúp ứng dụng ngừng theo đuổi kết quả không còn cần thiết. Nó nên đi cùng quản lý vòng đời và trạng thái rõ ràng, không được dùng như bằng chứng rằng server đã hoàn tác công việc.




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