Memahami Async/Await di JavaScript Sampai ke Akarnya

Async/await bukan magic — di baliknya ada Event Loop, Call Stack, dan Promise yang bekerja. Pahami cara kerjanya dan kamu tidak akan pernah bingung lagi.
Memahami Async/Await di JavaScript Sampai ke Akarnya

Banyak developer JavaScript yang bisa pakai async/await tapi tidak bisa jelaskan kenapa kode tertentu berperilaku tidak seperti yang diharapkan. Ini karena mereka skip memahami fondasi di bawahnya.

JavaScript Adalah Single-Threaded

JavaScript hanya punya satu thread — artinya satu hal terjadi pada satu waktu. Tapi website bisa fetch data sambil animasi berjalan sambil user bisa scroll. Bagaimana?

Event Loop: Jantung Async JavaScript

Ada tiga komponen utama:

  • Call Stack — tempat fungsi yang sedang dieksekusi
  • Web APIs — tempat operasi async ditangani browser (setTimeout, fetch, event)
  • Callback Queue — antrian callback yang menunggu dieksekusi

Event Loop tugasnya sederhana: kalau Call Stack kosong, ambil item pertama dari Queue dan masukkan ke Stack.

Dari Callback ke Promise ke Async/Await

Era Callback (masalah: callback hell)

getUserData(userId, function(user) {
  getOrders(user.id, function(orders) {
    getOrderDetails(orders[0].id, function(details) {
      // Sudah 3 level — bayangkan kalau lebih dalam
    });
  });
});

Era Promise (lebih baik, tapi masih verbose)

getUserData(userId)
  .then(user => getOrders(user.id))
  .then(orders => getOrderDetails(orders[0].id))
  .then(details => console.log(details))
  .catch(error => console.error(error));

Era Async/Await (paling readable)

async function loadUserDetails(userId) {
  try {
    const user = await getUserData(userId);
    const orders = await getOrders(user.id);
    const details = await getOrderDetails(orders[0].id);
    return details;
  } catch (error) {
    console.error("Gagal load data:", error);
  }
}

Kesalahan Umum: Await Berurutan yang Tidak Perlu

// LAMBAT — request dijalankan berurutan (sequential)
// Total waktu: waktu request A + waktu request B
const userProfile = await fetchUserProfile(id);
const userPosts = await fetchUserPosts(id);

// CEPAT — request dijalankan bersamaan (parallel)
// Total waktu: waktu request yang paling lama
const [userProfile, userPosts] = await Promise.all([
  fetchUserProfile(id),
  fetchUserPosts(id)
]);

Promise.all vs Promise.allSettled vs Promise.race

// Promise.all — gagal jika salah satu request gagal
const [a, b] = await Promise.all([fetchA(), fetchB()]);

// Promise.allSettled — tunggu semua selesai, meski ada yang gagal
const results = await Promise.allSettled([fetchA(), fetchB()]);
results.forEach(r => {
  if (r.status === "fulfilled") console.log(r.value);
  if (r.status === "rejected") console.error(r.reason);
});

// Promise.race — ambil hasil dari yang pertama selesai
const fastest = await Promise.race([fetchFromServer1(), fetchFromServer2()]);

Async/Await Bukan Pengganti Promise

Async/await adalah syntactic sugar di atas Promise. Di baliknya, semua masih Promise. Memahami Promise akan membuatmu jauh lebih efektif menggunakan async/await.

Butuh Solusi Digital Custom?

Kami siap membuatkan solusi digital sesuai kebutuhan bisnis Anda.

Konsultasi Gratis