fetchaborttimeoutheaderMahir4 mnt baca

Fetch Lanjutan: Header, Timeout, dan Abort

Mengirim header auth, membatalkan request dengan AbortController, dan membuat timeout sendiri.

Kamu janjian ketemu teman, tapi setelah 30 menit dia tidak muncul dan tidak bisa dihubungi. Berapa lama kamu menunggu sebelum pulang? fetch() bawaan tidak punya batas waktu: kalau server menggantung tanpa menjawab, request-mu menggantung selamanya. Di sinilah AbortController berperan sebagai "alarm pengingat".

Kenapa timeout itu wajib

Tanpa timeout, satu API lambat bisa membekukan seluruh aplikasi: loading spinner berputar tanpa akhir, user tidak tahu apa yang terjadi. Timeout mengubah ketidakpastian menjadi kepastian: "kalau 10 detik tidak ada jawaban, anggap gagal dan beri tahu user." Ini fondasi aplikasi yang responsif.

Contoh 1: fetch dengan timeout manual

javascript
const controller = new AbortController();
const timeoutId = setTimeout(function() {
  controller.abort();
}, 10000);

try {
  const response = await fetch("https://api.contoh.id/data", {
    signal: controller.signal
  });
  clearTimeout(timeoutId);
  const data = await response.json();
  console.log(data);
} catch (e) {
  if (e.name === "AbortError") {
    console.log("Request dibatalkan: timeout 10 detik");
  }
}

AbortController menghasilkan signal yang disambungkan ke fetch. Saat abort() dipanggil, fetch melempar error bernama AbortError. Jangan lupa clearTimeout saat sukses agar timer tidak bocor.

Contoh 2: mengirim header kustom plus timeout

javascript
async function getProfil(token) {
  const controller = new AbortController();
  const timer = setTimeout(function() { controller.abort(); }, 8000);

  try {
    const response = await fetch("https://api.contoh.id/profil", {
      method: "GET",
      headers: {
        "Authorization": "Bearer " + token,
        "Accept": "application/json"
      },
      signal: controller.signal
    });
    if (!response.ok) throw new Error("HTTP " + response.status);
    return await response.json();
  } finally {
    clearTimeout(timer);
  }
}

Pola ini menggabungkan semuanya: header auth, pengecekan status, timeout, dan pembersihan timer di finally agar selalu jalan baik sukses maupun gagal. Jadikan fungsi helper seperti ini standar di project-mu.

Kesalahan umum

Salah: tidak membersihkan timer. setTimeout yang tidak di-clear menumpuk dan membocorkan memori. Yang benar: selalu clearTimeout di jalur sukses maupun di finally.

Salah: timeout terlalu pendek untuk semua request. Upload file butuh waktu lebih lama dari sekadar ambil profil. Yang benar: sesuaikan durasi timeout dengan jenis request (misalnya 10 detik untuk GET, 60 detik untuk upload).

Salah: tidak membedakan AbortError dengan error lain. Semua error diperlakukan sama, padahal timeout butuh pesan khusus ("server lama merespons, coba lagi"). Yang benar: cek e.name === "AbortError" dan beri pesan yang sesuai.

Memilih durasi timeout yang tepat

Tidak ada angka ajaib; sesuaikan dengan jenis request:

Jenis requestTimeout wajar
GET data kecil10 detik
POST form15 detik
Upload file60-120 detik
Request real-time5 detik

Terlalu pendek: request valid dibatalkan sia-sia. Terlalu panjang: user menunggu tanpa kepastian. Untuk upload besar, pertimbangkan chunked upload (potong file jadi bagian kecil) daripada timeout raksasa.

Catatan teknis: AbortController juga bisa membatalkan banyak request sekaligus dengan satu signal, berguna saat user pindah halaman: batalkan semua request halaman lama agar tidak membuang bandwidth dan menimpa state halaman baru.

Live Playground
export default function App(): JSX.Element {
  return <h1>Hello world</h1>
}

Edit kode di kiri, preview kanan ter-update otomatis.

Tantangan

Bungkus fetch dengan timeout

Tulis fungsi fetchTimeout(url, ms) seperti di materi, lalu uji:

  1. Panggil dengan https://httpbin.org/delay/5 dan timeout 2000ms. Pastikan ia melempar AbortError setelah ~2 detik, bukan menunggu 5 detik.
  2. Panggil dengan https://jsonplaceholder.typicode.com/posts/1 dan timeout 5000ms. Pastikan sukses normal.
  3. Jelaskan kenapa clearTimeout ditaruh di finally.