Bahasa Indonesia

Pelajari cara menggunakan AbortController JavaScript untuk membatalkan operasi asinkron seperti permintaan fetch, timer, dan lainnya secara efektif, memastikan kode yang lebih bersih dan berperforma.

JavaScript AbortController: Menguasai Pembatalan Operasi Asinkron

Dalam pengembangan web modern, operasi asinkron ada di mana-mana. Mengambil data dari API, mengatur timer, dan menangani interaksi pengguna sering kali melibatkan kode yang berjalan secara independen dan berpotensi untuk durasi yang lama. Namun, ada skenario di mana Anda perlu membatalkan operasi ini sebelum selesai. Di sinilah antarmuka AbortController di JavaScript datang untuk menyelamatkan. Ini menyediakan cara yang bersih dan efisien untuk mengirim sinyal permintaan pembatalan ke operasi DOM dan tugas asinkron lainnya.

Memahami Kebutuhan Pembatalan

Sebelum mendalami detail teknis, mari kita pahami mengapa pembatalan operasi asinkron itu penting. Pertimbangkan skenario umum berikut:

Memperkenalkan AbortController dan AbortSignal

Antarmuka AbortController dirancang untuk menyelesaikan masalah pembatalan operasi asinkron. Ini terdiri dari dua komponen kunci:

Penggunaan Dasar: Membatalkan Permintaan Fetch

Mari kita mulai dengan contoh sederhana membatalkan permintaan fetch:


const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.example.com/data', { signal })
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    console.log('Data:', data);
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Fetch aborted');
    } else {
      console.error('Fetch error:', error);
    }
  });

// To cancel the fetch request:
controller.abort();

Penjelasan:

  1. Kita membuat instance AbortController.
  2. Kita mendapatkan AbortSignal yang terkait dari controller.
  3. Kita meneruskan signal ke opsi fetch.
  4. Jika kita perlu membatalkan permintaan, kita memanggil controller.abort().
  5. Di blok .catch(), kita memeriksa apakah kesalahannya adalah AbortError. Jika ya, kita tahu bahwa permintaan telah dibatalkan.

Menangani AbortError

Ketika controller.abort() dipanggil, permintaan fetch akan ditolak dengan AbortError. Sangat penting untuk menangani kesalahan ini dengan tepat dalam kode Anda. Kegagalan untuk melakukannya dapat menyebabkan penolakan promise yang tidak ditangani dan perilaku yang tidak terduga.

Berikut adalah contoh yang lebih kuat dengan penanganan kesalahan:


const controller = new AbortController();
const signal = controller.signal;

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data', { signal });
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    console.log('Data:', data);
    return data;
  } catch (error) {
    if (error.name === 'AbortError') {
      console.log('Fetch aborted');
      return null; // Or throw the error to be handled further up
    } else {
      console.error('Fetch error:', error);
      throw error; // Re-throw the error to be handled further up
    }
  }
}

fetchData();

// To cancel the fetch request:
controller.abort();

Praktik Terbaik untuk Menangani AbortError:

Membatalkan Timer dengan AbortSignal

AbortSignal juga dapat digunakan untuk membatalkan timer yang dibuat dengan setTimeout atau setInterval. Ini memerlukan sedikit lebih banyak pekerjaan manual, karena fungsi timer bawaan tidak secara langsung mendukung AbortSignal. Anda perlu membuat fungsi kustom yang mendengarkan sinyal pembatalan dan membersihkan timer saat sinyal tersebut dipicu.


function cancellableTimeout(callback, delay, signal) {
  let timeoutId;

  const timeoutPromise = new Promise((resolve, reject) => {
    timeoutId = setTimeout(() => {
      resolve(callback());
    }, delay);

    signal.addEventListener('abort', () => {
      clearTimeout(timeoutId);
      reject(new Error('Timeout Aborted'));
    });
  });

  return timeoutPromise;
}

const controller = new AbortController();
const signal = controller.signal;


cancellableTimeout(() => {
  console.log('Timeout executed');
}, 2000, signal)
.then(() => console.log("Timeout finished successfully"))
.catch(err => console.log(err));

// To cancel the timeout:
controller.abort();

Penjelasan:

  1. Fungsi cancellableTimeout menerima callback, penundaan (delay), dan AbortSignal sebagai argumen.
  2. Fungsi ini menyiapkan setTimeout dan menyimpan ID timeout.
  3. Fungsi ini menambahkan event listener ke AbortSignal yang mendengarkan event abort.
  4. Ketika event abort dipicu, event listener akan membersihkan timeout dan menolak promise.

Membatalkan Event Listener

Mirip dengan timer, Anda dapat menggunakan AbortSignal untuk membatalkan event listener. Ini sangat berguna ketika Anda ingin menghapus event listener yang terkait dengan komponen yang sedang dilepas (unmounted).


const controller = new AbortController();
const signal = controller.signal;

const button = document.getElementById('myButton');

button.addEventListener('click', () => {
  console.log('Button clicked!');
}, { signal });

// To cancel the event listener:
controller.abort();

Penjelasan:

  1. Kita meneruskan signal sebagai opsi ke metode addEventListener.
  2. Ketika controller.abort() dipanggil, event listener akan dihapus secara otomatis.

AbortController dalam Komponen React

Di React, Anda dapat menggunakan AbortController untuk membatalkan operasi asinkron saat komponen dilepas (unmount). Ini penting untuk mencegah kebocoran memori dan kesalahan yang disebabkan oleh pembaruan komponen yang sudah dilepas. Berikut adalah contoh menggunakan hook useEffect:


import React, { useState, useEffect } from 'react';

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;

    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data', { signal });
        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }
        const data = await response.json();
        setData(data);
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Fetch aborted');
        } else {
          console.error('Fetch error:', error);
        }
      }
    }

    fetchData();

    return () => {
      controller.abort(); // Cancel the fetch request when the component unmounts
    };
  }, []); // Empty dependency array ensures this effect runs only once on mount

  return (
    
{data ? (

Data: {JSON.stringify(data)}

) : (

Loading...

)}
); } export default MyComponent;

Penjelasan:

  1. Kita membuat AbortController di dalam hook useEffect.
  2. Kita meneruskan signal ke permintaan fetch.
  3. Kita mengembalikan fungsi pembersihan (cleanup function) dari hook useEffect. Fungsi ini akan dipanggil saat komponen dilepas (unmount).
  4. Di dalam fungsi pembersihan, kita memanggil controller.abort() untuk membatalkan permintaan fetch.

Kasus Penggunaan Lanjutan

Merangkai AbortSignal

Terkadang, Anda mungkin ingin merangkai beberapa AbortSignal bersama-sama. Misalnya, Anda mungkin memiliki komponen induk yang perlu membatalkan operasi di komponen anaknya. Anda dapat mencapai ini dengan membuat AbortController baru dan meneruskan sinyalnya ke komponen induk dan anak.

Menggunakan AbortController dengan Pustaka Pihak Ketiga

Jika Anda menggunakan pustaka pihak ketiga yang tidak secara langsung mendukung AbortSignal, Anda mungkin perlu menyesuaikan kode Anda agar berfungsi dengan mekanisme pembatalan pustaka tersebut. Ini mungkin melibatkan pembungkusan fungsi asinkron pustaka dalam fungsi Anda sendiri yang menangani AbortSignal.

Manfaat Menggunakan AbortController

Kompatibilitas Browser

AbortController didukung secara luas di browser modern, termasuk Chrome, Firefox, Safari, dan Edge. Anda dapat memeriksa tabel kompatibilitas di MDN Web Docs untuk informasi terbaru.

Polyfill

Untuk browser lama yang tidak mendukung AbortController secara native, Anda dapat menggunakan polyfill. Polyfill adalah sepotong kode yang menyediakan fungsionalitas fitur baru di browser lama. Ada beberapa polyfill AbortController yang tersedia secara online.

Kesimpulan

Antarmuka AbortController adalah alat yang ampuh untuk mengelola operasi asinkron di JavaScript. Dengan menggunakan AbortController, Anda dapat menulis kode yang lebih bersih, lebih berperforma, dan lebih kuat yang menangani pembatalan dengan baik. Baik Anda mengambil data dari API, mengatur timer, atau mengelola event listener, AbortController dapat membantu Anda meningkatkan kualitas keseluruhan aplikasi web Anda.

Bacaan Lebih Lanjut