Sebelum Mulai: Apa yang Perlu Kamu Siapkan?

Sebelum menyelami dunia async/await, pastikan kamu sudah mengerti dasar-dasar JavaScript seperti variabel, fungsi, dan khususnya Promise. Jika belum familiar dengan Promise, jangan khawatir – tutorial ini akan mengulasnya secara singkat. Kamu hanya perlu:

  • Browser modern (Chrome, Firefox, atau Edge) atau Node.js versi 8+.
  • Text editor seperti VS Code.
  • Semangat belajar yang tinggi!

Kenapa Kita Butuh Async/Await?

JavaScript secara default berjalan synchronous – satu per satu. Tapi banyak tugas di web development seperti mengambil data dari server, membaca file, atau menunggu timer membutuhkan waktu yang tidak bisa diprediksi. Bayangkan saat kamu memesan kopi di kafe: jika kamu harus menunggu sampai pesanan selesai sebelum bisa ngobrol dengan teman, itu namanya blocking. Async programming memungkinkan kamu 'memesan' kopi lalu tetap bisa ngobrol sambil menunggu.

Dulu kita menggunakan callback untuk menangani kode asynchronous, tapi callback bisa menyebabkan 'callback hell' yang sulit dibaca. Kemudian Promise hadir membuat kode lebih rapi, namun masih ada banyak .then() dan .catch(). Inilah kenapa async/await diciptakan – untuk membuat kode asynchronous terlihat dan berperilaku seperti kode synchronous, lebih mudah dibaca dan di-debug.

Mengulang Konsep Promise Secara Cepat

Promise adalah objek yang mewakili nilai yang mungkin belum tersedia sekarang, tapi akan tersedia di masa depan. Promise memiliki tiga status: pending, fulfilled, atau rejected. Mari buat fungsi yang mengembalikan Promise untuk simulasi mengambil data dari server:

function ambilDataUser() {
  return new Promise((resolve, reject) => {
    // Simulasi request server selama 2 detik
    setTimeout(() => {
      const sukses = true; // ganti jadi false untuk lihat error
      if (sukses) {
        resolve({ nama: 'Budi', umur: 25 });
      } else {
        reject(new Error('Gagal mengambil data'));
      }
    }, 2000);
  });
}

// Cara menggunakan Promise
ambilDataUser()
  .then((data) => console.log('Data diterima:', data))
  .catch((err) => console.error('Error:', err.message));

Kode di atas berfungsi, tapi perhatikan: kita harus menulis .then() dan .catch() secara eksplisit. Bayangkan jika ada tiga request berurutan – akan berbunyi .then().then().then()....

Async/Await: Janji Manis yang Disempurnakan

Async/await adalah sintaks yang dibangun di atas Promise. Kata kunci async digunakan pada sebuah fungsi untuk menandai bahwa fungsi tersebut akan menggunakan await. await akan 'menunggu' Promise selesai (resolve atau reject) dan mengembalikan nilai resolve-nya. Fungsi yang menggunakan async secara otomatis mengembalikan Promise.

Mari ubah contoh sebelumnya ke async/await:

async function prosesAmbilData() {
  try {
    const data = await ambilDataUser();
    console.log('Data diterima:', data);
  } catch (error) {
    console.error('Terjadi error:', error.message);
  }
}

prosesAmbilData();

Lihat perbedaannya? Kode di atas terlihat seperti kode synchronous, tapi sebenarnya asynchronous. Kita menggunakan try/catch untuk menangani error, bukan .catch(). Jauh lebih bersih!

Contoh Praktis: Mengambil Data dari API Publik

Sekarang kita buat contoh nyata menggunakan JSONPlaceholder (API palsu untuk latihan). Kita akan mengambil data pengguna dan menampilkannya.

Pertama, kita buat fungsi untuk fetch data:

async function ambilDaftarUser() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/users');
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const users = await response.json();
    return users;
  } catch (error) {
    console.error('Gagal mengambil user:', error);
    throw error; // lempar lagi biar bisa ditangani oleh pemanggil
  }
}

// Fungsi utama yang memanggil dan menampilkan
async function tampilkanUser() {
  try {
    const daftarUser = await ambilDaftarUser();
    daftarUser.forEach((user) => {
      console.log(`${user.name} - ${user.email}`);
    });
  } catch (error) {
    console.log('Tidak dapat menampilkan user.');
  }
}

tampilkanUser();

Perhatikan: Kita menggunakan fetch yang mengembalikan Promise. Dengan await, kita bisa menunggu respons dan kemudian mengubahnya ke JSON. Semua error ditangani di blok try/catch.

Menangani Banyak Operasi Async Secara Bersamaan

Terkadang kita perlu menjalankan beberapa async task secara paralel. Misalnya ingin mengambil data pengguna dan data postingan secara bersamaan, bukan satu per satu. Di sinilah Promise.all() berguna, dan kita bisa kombinasikan dengan async/await:

async function ambilDataParalel() {
  try {
    const [users, posts] = await Promise.all([
      fetch('https://jsonplaceholder.typicode.com/users').then(res => res.json()),
      fetch('https://jsonplaceholder.typicode.com/posts').then(res => res.json())
    ]);
    console.log('Jumlah user:', users.length);
    console.log('Jumlah posting:', posts.length);
  } catch (error) {
    console.error('Salah satu request gagal:', error);
  }
}

ambilDataParalel();

Dengan Promise.all, kedua request berjalan bersamaan, bukan menunggu satu selesai dulu. Ini menghemat waktu.

Kesalahan Umum dan Cara Menghindarinya

  1. Lupa menambahkan await – Fungsi async akan tetap mengembalikan Promise, jadi jika lupa await, variabel akan berisi Promise, bukan data aktual.
const data = ambilDaftarUser(); // SALAH: data adalah Promise, bukan array
  1. Menggunakan await di luar fungsi async – await hanya valid di dalam fungsi yang ditandai async. Di top-level kode (misal skrip global), gunakan IIFE:
(async () => {
     const data = await ambilDaftarUser();
     console.log(data);
   })();
  1. Tidak menangani error – Selalu gunakan try/catch atau tambahkan .catch() pada Promise yang dikembalikan oleh fungsi async.
  2. Async loop yang salah – Jika perlu melakukan loop dengan async, gunakan for...of dengan await, bukan forEach yang tidak menunggu Promise.

Tips & Saran dari Praktisi

Gunakan async/await untuk kode yang lebih bersih, terutama untuk operasi berantai. Namun tetap pahami Promise, karena beberapa pattern (seperti Promise.all, Promise.race) tetap diperlukan. Saat bekerja dengan proyek besar dan membutuhkan alat bantu seperti VPN untuk mengakses resource global, kamu bisa memanfaatkan layanan yang stabil untuk menjaga produktivitas coding tetap optimal.

Sponsored Deal

Jangan ragu untuk bereksperimen di console browser atau Node.js. Semakin sering mencoba, semakin paham kamu tentang alur async.

Troubleshooting: Saat Kode Tidak Berjalan seperti Harapan

  • Promise tidak pernah resolve? Pastikan tidak ada kesalahan logika di dalam Promise (misal lupa panggil resolve()).
  • Error 'await is only valid in async function' – Pastikan fungsi pembungkus sudah ditandai async.
  • Data undefined setelah await? Cek apakah URL API benar dan responsnya valid. Kadang perlu response.json() atau response.text().
  • Callback hell masih muncul? Coba refaktor dengan fungsi async terpisah atau gunakan Promise.all().

Kesimpulan

Async/await adalah alat powerful yang membuat JavaScript asynchronous mudah dibaca dan ditulis. Mulailah dari contoh sederhana, lalu coba integrasikan ke proyek kecil. Ingat, latihan adalah kunci. Selamat coding!