🌞

Một vài ứng dụng của AbortController

Sửa bài viết này

Món đồ chơi mới AbortController (ý là thằng bạn trình duyệt cũ không chịu chơi chung) cho phép chúng ta hủy một tác vụ đang chạy, tác dụ hay gặp nhất là việc fetching data

const controller = new AbortController()

await fetch('vuilaptrinh.com', { signal: controller.signal })

// dừng lại anh ơi
controller.abort()

Trước khi có AbortController đố bạn có cách nào để ngưng việc fetch một khi đã báo nó chạy đi em

controller.signal ở trên mang giá trị state, mọi thứ được xử lý bên trong AbortController, chúng ta chỉ khai báo với anh fetch có thay đổi state thì truyền vào đây giúp em nhé

Chúng ta sẽ tham khảo một vài ứng dụng của AbortController nào

Xóa Event Handler

Nếu chúng ta muốn hủy đăng ký một trên event để tránh ngốn RAM của user

window.addEventListener('resize', () => { /* do something */});

// hủy đăng ký
window.removeEventListener('resize', () => { /* do something */});

Nhưng nếu nhìn kỹ, chúng ta sẽ ngộ ra cái () => doSomething() truyền cho addEventListenerremoveEventListener hoàn toàn khác nhau, nghĩa là việc chúng ta làm là công cốc rồi. Đúng ra chúng ta phải viết

window.addEventListener('resize', doSomething);
window.removeEventListener('resize', doSomething);

Nhưng nếu lỡ chúng ta đã khoái arrow function và hông khoái cái removeEventListener. Chúng ta có thể dùng AbortController

const controller = new AbortController();
const { signal } = controller;

window.addEventListener('resize', () => { /* do something */}, { signal })

// unregister nè
controller.abort()

Lưu ý Chrome cũ không chạy và Safari dưới 15 không chạy

Async trong React hook

Xung quanh việc làm cái gì bên trong useEffect có khá nhiều quan điểm, số lượng người dùng useEffect để fetching data cũng không phải ít. Nói chung cũng ok thôi, và sử dụng async bên trong useEffect đúng là một canh bạc hên xui mai rũi, xui xui chưa fetch xong user lạng qua trang khác thì biết chuyện gì xảy ra rồi, nó vẫn fetching cho xong dữ liệu

function VuiComponent() {
	useEffect(async () => {
		const res = await fetch('url')
	}, [])
	return (<div />) 
}

Để đảm bảm khi component chúng ta bị remove, nó phải hủy luôn việc fetching

function VuiComponent() {
	useEffect(() => {
		const controller = new AbortController();
		const { signal } = controller;

		(async () => {
			const res = await fetch('url')
		})();

		return () => controller.abort();
	}, [])
	
	return (<div />) 
}

Một điểm rất đáng để tâm trong React là sau khi await cú call đầu tiên, nếu chúng ta lấy state bên trong hàm async không hẳn nó là giá trị mới nhất, rất có thể nó lấy giá trị trước đó

function KhongVuiComponent() {
	const [value, setValue] = useState(0);

	useEffect(async () => {
    await new Promise((r) => setTimeout(r, 1000));

    console.log(value)
    // Ở đây không chắc value lúc nào cũng = giá trị sau khi click button nha
  }, []);

	return <button onClick={() => setValue((v) => v + 1)}>Increment</button>
}
fetchButton.onclick = async () => {
	const controller = new AbortController();
	
}

Initializing...