Topik temu duga representatif

Temu duga Frontend: Bagaimanakah anda menggunakan AbortSignal.timeout dan any untuk membatalkan permintaan?

FrontendSederhana
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Halaman carian mesti membatalkan fetch apabila pengguna keluar, permintaan tamat masa, atau komponen dinyahlekap (unmount). Bandingkan AbortSignal.timeout, AbortSignal.any, dan AbortController, bezakan TimeoutError daripada AbortError, serta cadangkan kaedah sandaran (fallback) dan pengesahan.

Gesaan dan konteks

Halaman carian meminta cadangan carian, data profil dan hasil carian secara serentak. Pertanyaan baharu atau navigasi sepatutnya membatalkan kerja lama dengan pantas; permintaan rangkaian yang terhenti sepatutnya tamat masa, tetapi kembali dari latar belakang tidak boleh mengira masa beku sebagai masa permintaan dalam talian. Reka bentuk pembatalan dengan AbortSignal.timeout(), AbortSignal.any() dan AbortController.

Ini sesuai untuk temu duga frontend, prestasi Web dan seni bina tak segerak (asynchronous). Kuncinya adalah mengasingkan pembatalan pengguna, tamat masa, kitaran hayat halaman dan kegagalan rangkaian sebenar daripada memaparkan setiap pengecualian sebagai "permintaan telah tamat masa."

Perkara yang diuji oleh penemu duga

Jawapan yang mantap menyatakan bahawa AbortSignal.timeout() mengembalikan isyarat yang terbatal secara automatik dengan TimeoutError; pembatalan pengguna atau pengawal biasanya adalah AbortError. Ia juga menerangkan semantik masa aktif: pemasa dijeda semasa halaman berada dalam bfcache atau Worker digantung. Pelbagai isyarat boleh digabungkan dengan AbortSignal.any() sambil mengekalkan sebab yang boleh didiagnosis.

Soalan penjelasan untuk ditanya terlebih dahulu

  • Permintaan manakah yang selamat untuk dibatalkan, dan adakah operasi tulis mesti diselesaikan atau disemak statusnya kemudian?
  • Adakah tamat masa bermula pada tindakan pengguna, penghantaran permintaan, atau keterlihatan halaman?
  • Adakah pembatalan pengguna, penyahlekapan (unmount), navigasi dan tamat masa memerlukan pemesejan yang berbeza?
  • Adakah pelayar sasaran menyokong kaedah statik tersebut, dan patutkah sandaran mengekalkan pemasa manual?
  • Bagaimanakah percubaan semula, penyahduplikasian, penimbalan (caching) dan perlumbaan hasil (result races) dikendalikan?

Kerangka jawapan 30 saat

"Bagi setiap permintaan, saya akan menggabungkan pembatalan pengguna dengan AbortSignal.timeout() dan mengelaskan TimeoutError, AbortError serta ralat rangkaian secara berasingan. Tamat masa menggunakan masa aktif, jadi penggantungan atau bfcache tidak dilaporkan sebagai kependaman dalam talian. Pertanyaan baharu membatalkan pengawal lama, dan penyerahan hasil juga menyemak jujukan permintaan atau isyarat supaya data lapuk tidak diguna pakai. Pelayar lama menerima sandaran pengawal bersama pemasa, yang diuji untuk pembatalan, tamat masa, penyambungan semula dan keadaan perlumbaan."

Jawapan mendalam langkah demi langkah

Langkah 1: Asingkan tiga sumber pembatalan

AbortController.abort() dimulakan oleh aplikasi; AbortSignal.timeout(ms) terbatal apabila masa aktif mencapai had; AbortSignal.any([...]) dicetuskan apabila mana-mana isyarat input terbatal. Kesemuanya boleh diserahkan kepada fetch, tetapi lapisan perniagaan harus mengekalkan sebabnya supaya tindakan meninggalkan halaman tidak dilog sebagai kegagalan perkhidmatan.

js
const controller = new AbortController();
const timeout = AbortSignal.timeout(5000);
const signal = AbortSignal.any([controller.signal, timeout]);

fetch(url, { signal });

Langkah 2: Kelaskan mengikut sebab

Tamat masa menggunakan DOMException TimeoutError; pembatalan pengguna atau pemberhentian pelayar lazimnya menggunakan AbortError. Isu DNS, tetapan semula sambungan dan CORS mungkin muncul sebagai ralat lain. Kod yang menangkap pengecualian harus memeriksa signal.reason atau nama pengecualian sebelum memilih pemesejan, percubaan semula dan tahap keterukan log.

Langkah 3: Fahami masa aktif

timeout() mengukur masa aktif dan bukannya jam dinding mudah. Dokumentasi menyatakan bahawa pemasa dijeda semasa halaman berada dalam bfcache atau Worker digantung. Ini sesuai untuk tempoh permintaan aktif yang dirasai pengguna, bukan batas masa pelayan yang mutlak; pelayan masih memerlukan dasar tamat masa dan keidempotensian tersendiri.

Langkah 4: Kendalikan perlumbaan carian

Apabila pengguna menaip secara berulang, batalkan pengawal lama sebelum mencipta isyarat untuk pertanyaan baharu. Walaupun kerja rangkaian lama telah selesai, panggilan baliknya mungkin masih berada dalam giliran; semak jujukan permintaan, pertanyaan semasa, atau signal.aborted sebelum melakukan komit keadaan. Pembatalan sahaja tidak menjamin susunan versi hasil.

Langkah 5: Asingkan operasi baca dan tulis yang boleh dibatalkan

Operasi membaca carian, imej dan cadangan biasanya boleh dibatalkan. Operasi menulis seperti pembayaran, pesanan atau muat naik mungkin telah berkuat kuasa pada pelayan. Membatalkan penantian pelanggan tidak membatalkan kesan sampingan pelayan. Gunakan kunci keidempotensian, pertanyaan status atau tugas latar belakang untuk operasi tulis daripada sekadar memilih tamat masa yang lebih singkat.

Langkah 6: Reka bentuk jangka hayat isyarat

Batalkan pengawal komponen semasa penyahlekapan, guna semula isyarat peringkat halaman semasa navigasi, dan tambah tamat masa permintaan bagi operasi individu. Jangan sekali-kali berkongsi isyarat global yang telah dibatalkan secara kekal dengan permintaan terkemudian; cipta isyarat baharu bagi setiap operasi. Berikan sebab yang jelas kepada sumber berbeza apabila diagnostik diperlukan.

Langkah 7: Sediakan sandaran keserasian

Jika pelayar lama tidak mempunyai AbortSignal.timeout atau any, gabungkan AbortController dengan setTimeout, kosongkan pemasa dan normalkan sebabnya. Pengesanan ciri harus dibuat pada masa larian (runtime), dan laluan lalai mesti terus mengendalikan persekitaran tanpa kaedah statik tersebut.

Langkah 8: Sahkan kitaran hayat dan pembersihan

Uji input pantas, penyahlekapan, navigasi, penggantungan latar belakang, pemulihan bfcache, tamat masa, pembatalan pengguna, kegagalan rangkaian dan percubaan semula berulang. Sahkan bahawa permintaan dibatalkan, pemasa dikosongkan, hasil lapuk tidak dikomit, mesej adalah tepat, dan penangkapan pengecualian tidak menghasilkan janji (promise) yang tidak dikendalikan atau amaran kemas kini keadaan.

Pertukaran kompromi dan sempadan

Isyarat gabungan mengurangkan kod penyambung pembatalan, tetapi ia tidak menjadikan transaksi pelayan boleh diundur atau menjamin bahawa respons tidak akan tiba sama sekali. Semantik masa aktif sesuai untuk pengalaman pengguna tetapi bukan untuk SLA hujung-ke-hujung. Tetapkan nilai tamat masa mengikut jenis permintaan, keadaan rangkaian dan belanjawan percubaan semula, diselaraskan dengan batas masa pelayan.

Jangan hanya menggunakan Promise.race untuk mensimulasikan tamat masa dan membiarkan permintaan asas terus berjalan. Serahkan AbortSignal supaya rangkaian dan sumber dapat dihentikan. Jangan log setiap pembatalan sebagai ralat, jika tidak, navigasi biasa akan mencemari amaran sistem.

Pelan pelancaran dan bukti

Mulakan dengan mesin keadaan (state machine) permintaan untuk operasi baca carian: cipta isyarat, hantar, kelaskan sebab, komit hasil berversi dan batalkan semasa penyahlekapan. Rekodkan jenis permintaan, sebab, tempoh aktif, bilangan percubaan semula dan keadaan akhir tanpa menyertakan teks pertanyaan yang sensitif.

Bandingkan pelayar yang disokong dan pelayar sandaran merentasi bfcache, Workers, rangkaian perlahan dan input pantas. Penerimaan memerlukan tiada penulisan ganti oleh hasil lapuk, tiada kebocoran pemasa, pemesejan pembatalan yang tepat, tiada pembatalan operasi tulis yang tidak disengajakan, dan bukti keidempotensian pelayan atau semakan status.

Perangkap biasa dan tindakan susulan

Mengelirukan TimeoutError dan AbortError

Pembatalan pengguna, penyahlekapan dan tamat masa mempunyai langkah seterusnya yang berbeza. Kelaskan mengikut sebab untuk memilih pemesejan, pengelogan dan percubaan semula.

Menganggap pembatalan pelanggan mengundur balik operasi tulis pelayan

Permintaan mungkin telah sampai ke pelayan. Operasi tulis memerlukan kunci keidempotensian, pertanyaan status atau aliran pampasan.

Menggantikan pembatalan sebenar dengan Promise.race

Menggunakan race mengubah perkara yang ditunggu oleh pemanggil tetapi tidak menghentikan fetch asas. Serahkan AbortSignal dan bersihkan sumber.

Mengabaikan masa aktif berkaitan bfcache

Tamat masa mungkin dijeda semasa halaman digantung. Jangan anggap tempoh selepas pemulihan sebagai SLA permintaan dalam talian.

Bagaimanakah anda menghalang hasil lama daripada diguna pakai?

Membatalkan pengawal lama tidak mencukupi. Bandingkan jujukan pertanyaan, versi atau pertanyaan semasa sebelum melakukan komit supaya susunan respons tidak dapat mengubah keadaan.

Sumber awam

Soalan berkaitan