Pencarian sambil mengetik memiliki kegagalan klasik: pengguna mengetik lima huruf, lima permintaan diaktifkan, respons kedua datang terakhir, dan hasil lamanya menimpa respons kelima yang benar. Setiap perbaikan berakhir pada alat yang sama: AbortController.
let inFlight;
async function search(q) {
inFlight?.abort(); // cancel the previous query
inFlight = new AbortController();
try {
const res = await fetch(`/api/search?q=${encodeURIComponent(q)}`, {
signal: inFlight.signal,
});
render(await res.json());
} catch (err) {
if (err.name !== "AbortError") throw err; // aborts are expected
}
}
// cleanup when the component or page closes
addEventListener("pagehide", () => inFlight?.abort());Empat kebiasaan dalam cuplikan itu
- Satu pengontrol sedang terbang: membatalkannya juga membatalkan registrasi sinyalnya, sehingga permintaan lama berhenti memakan bandwidth dan CPU.
- AbortError adalah keadaan normal, bukan crash: telan saja, karena permintaan yang dibatalkan melakukan tugasnya dengan dibatalkan.
- Debounce masih membantu: membatalkan menghentikan bug hasil basi, melakukan debouncing menghentikan permintaan yang merupakan byte yang tidak ada gunanya sejak lahir.
- Batalkan juga saat pembongkaran: navigasi dan pelepasan komponen biarkan pengambilan tetap hidup.
Di mana lagi ia mendapatkan byte-nya
- Konten bertab tempat setiap tab diambil: beralih di tengah-tengah tanpa membatalkan adalah balapan yang sama.
- Aliran unggahan multi-file di mana pengguna seharusnya dapat membatalkan satu file, bukan keseluruhan batch.
- Putaran pemungutan suara yang dimulai ulang: interval baru harus menghentikan permintaan sebelumnya atau dua tanggapan datang dan bertengkar.
Halaman pencarian situs ini sengaja tidak memerlukan jaringan: indeks dikirimkan dalam halaman, sehingga perlombaan tidak dapat terjadi sama sekali, yang merupakan perbaikan paling gacor jika kumpulan data Anda cocok. Jika tidak, pembatalan akan mengalahkan segalanya, dan kodenya terdiri dari lima belas baris.
