Trong bài viết này mình sẽ chia sẻ với anh em một trick rất hay để refactor code khi removeEventListener
, bằng cách sử dụng AbortController.
Bài viết này đúc kết từ video trên kênh YouTube của Thiện
Vấn đề thực tế
Trong các dự án thực tế, khi anh em addEventListener
, chắc chắn anh em sẽ phải removeEventListener
khi không sử dụng để tránh tình trạng Memory Leak.
Ví dụ:
// Có 2 hàm xử lý sự kiện
function handleClick_1() { console.log('click 1');
} function handleClick_2() { console.log('click 2');
} // Add event listener
document.addEventListener('click', handleClick_1);
document.addEventListener('click', handleClick_2); // Remove event listener
function clearEventListener() { document.removeEventListener('click', handleClick_1); document.removeEventListener('click', handleClick_2);
}
Tuy nhiên, vấn đề bắt đầu nảy sinh, khi anh em cần thêm bất cứ sự kiện nào (mouseup, mousedown, click, ...) thì anh em sẽ phải thêm removeEventListener
tương ứng.
Ví dụ khi thêm mới sự kiện click, anh em sẽ cần removeEventListener
khi không còn sử dụng:
function handleClick_3() { console.log('click 3');
} document.addEventListener('click', handleClick_3); // Phải thêm remove
function clearEventListener() { document.removeEventListener('click', handleClick_1); document.removeEventListener('click', handleClick_2); document.removeEventListener('click', handleClick_3); // Thêm dòng này
}
Anh em sẽ thấy nó hơi dài dòng. Vì khi thêm 5, 10 sự kiện nữa, anh em bắt buộc phải thêm 5, 10 hàm removeEventListener
tương ứng.
Vậy có cách nào để refactor không?
Giải pháp: Sử dụng AbortController
Thông thường anh em hay sử dụng AbortController để hủy bỏ việc nhận response API từ server trả về. Nhưng ngoài công dụng trên, nó còn giúp anh em hủy bỏ các event listener.
Cách thực hiện
Bước 1: Tạo controller và signal
// Tạo AbortController
const controller = new AbortController(); // Tạo signal từ controller
const signal = controller.signal;
Bước 2: addEventListener với signal
function handleClick_1() { console.log('click 1');
} function handleClick_2() { console.log('click 2');
} // Điểm khác biệt: thêm tham số thứ 3
document.addEventListener('click', handleClick_1, { signal: signal
}); document.addEventListener('click', handleClick_2, { signal: signal
});
Điểm khác biệt quan trọng: Chúng ta thêm một tham số thứ 3 trong hàm addEventListener
. Đây là một object với key signal
và value tương ứng.
Bước 3: Clear tất cả event listener chỉ với 1 dòng code
function clearEventListener() { controller.abort(); // Chỉ cần 1 dòng này thôi!
}
Lợi ích khi thêm mới sự kiện
Khi anh em thêm addEventListener
, anh em sẽ không cần phải bổ sung thêm bất cứ removeEventListener
nào:
function handleClick_3() { console.log('click 3');
} // Chỉ cần addEventListener với signal
document.addEventListener('click', handleClick_3, { signal: signal
}); // KHÔNG cần thêm gì vào hàm clearEventListener
// Vì controller.abort() đã tự động clear tất cả!
Kết
Anh em nên sử dụng AbortController khi có nhiều event listener cần quản lý và muốn code clean, dễ maintain.
Lưu ý:
- AbortController hoạt động với các browser hiện đại (tại đây).
- Nên tạo controller riêng cho từng component/module.
1 phút Quảng cáo
Nếu anh em muốn có thêm nhiều kiến thức thú vị về tối ưu Frontend, anh em có thể đăng ký khoá học “Optimize Frontend for Beginner” của mình trên Udemy nhé. Hiện tại khoá học đang được ưu đãi nên anh em nhanh tay đăng ký ngay nha vì số lượng có hạn.
Link đăng ký khoá học tại đây nhé anh em:
https://www.udemy.com/course/optimize-frontend-for-beginner/?referralCode=96B9E7A8858C7A0CFE48
Đây là những gì anh em sẽ nắm được trong khoá học:
Anh em hãy kết nối với mình qua Youtube và LinkedIn để đọc nhiều bài viết hay khác nhé:
- Youtube: https://www.youtube.com/@pdthien
- LinkedIn: www.linkedin.com/in/pdthien