Asynchronous JavaScript: AJAX, Promise, Fetch, dan Async/Await

Oleh: Andi Ardiansyah Nasir Terakhir diperbarui: 10 Juni 2025

Pengantar Pemrograman Asynchronous

Pemrograman asynchronous memungkinkan JavaScript menjalankan operasi yang membutuhkan waktu (seperti request jaringan) tanpa memblokir eksekusi kode lainnya. Artikel ini akan membahas evolusi teknik asynchronous di JavaScript dari AJAX hingga async/await modern.

Kita akan mempelajari empat pendekatan utama: AJAX dengan XMLHttpRequest, Promise, Fetch API, dan async/await. Masing-masing memiliki kelebihan dan kasus penggunaan yang berbeda, dan memahami semuanya penting untuk pengembangan web modern.

1. Struktur HTML Umum (index.html)

Contoh HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>API Demo</title>
  <style>
    body { font-family: Arial; padding: 20px; }
    .user { margin-bottom: 10px; border-bottom: 1px solid #ccc; padding-bottom: 5px; }
    input, button { margin: 5px 0; }
  </style>
</head>
<body>
  <h2>📥 GET Data Pengguna</h2>
  <div id="user-container"></div>

  <h2>📤 POST Data Pengguna</h2>
  <input type="text" id="name" placeholder="Nama">
  <input type="email" id="email" placeholder="Email">
  <button onclick="postUser()">Kirim Data</button>

  <!-- Ganti script.js sesuai metode -->
  <script src="script.js"></script>
</body>
</html>

2. AJAX dengan XMLHttpRequest

AJAX (Asynchronous JavaScript and XML) adalah teknik lama untuk membuat request HTTP asynchronous menggunakan XMLHttpRequest.

Contoh AJAX

function showStatus(message, error = false) {
  const status = document.getElementById('status');
  status.textContent = message;
  status.style.color = error ? 'red' : 'green';
}

// fungsi untuk menampilkan data pengguna
function showUsers(users) {
  const container = document.getElementById('user-container');
  container.innerHTML = '';
  users.forEach(user => {
    const el = document.createElement('div');
    el.className = 'user';
    el.innerHTML = `${user.name}
${user.email}`; container.appendChild(el); }); } // fungsi untuk mendapatkan data pengguna function getUsers() { const xhr = new XMLHttpRequest(); xhr.open('GET', 'https://jsonplaceholder.typicode.com/users'); xhr.onload = function () { if (xhr.status === 200) { const data = JSON.parse(xhr.responseText); showUsers(data); } else { showStatus('Gagal memuat data. Status: ' + xhr.status, true); } }; xhr.onerror = function () { showStatus('Terjadi kesalahan jaringan.', true); }; xhr.send(); } // fungsi untuk mengirim data pengguna function postUser() { const name = document.getElementById('name').value.trim(); const email = document.getElementById('email').value.trim(); if (!name || !email) { return showStatus('Nama dan Email harus diisi.', true); } const xhr = new XMLHttpRequest(); xhr.open('POST', 'https://jsonplaceholder.typicode.com/users'); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function () { if (xhr.status === 201) { const data = JSON.parse(xhr.responseText); showStatus(`Berhasil kirim data: ${data.name}`); } else { showStatus('Gagal kirim data. Status: ' + xhr.status, true); } }; xhr.onerror = function () { showStatus('Terjadi kesalahan saat mengirim.', true); }; xhr.send(JSON.stringify({ name, email })); } getUsers();

2. Promise

Promise merupakan proxy untuk sebuah nilai di masa depan (Future) yang belum diketahui saat pembuatan Promise tersebut. Biasa Promise digunakan sebagai proxy untuk proses Async. Penggunaan Promise sangat mudah, dan lebih mirip dengan kode Synchronous.Promise memiliki tiga method yang bisa kita gunakan. then() untuk mendapatkan atau mengubah data ketika Promise sukses catch() untuk mendapatkan data error ketika Promise gagal finally() akan dieksekusi ketika terjadi sukses atau gagal pada Promise

Contoh Promise

// Fungsi untuk menampilkan data pengguna
function showUsers(users) {
  const container = document.getElementById('user-container');
  container.innerHTML = '';
  users.forEach(user => {
    const el = document.createElement('div');
    el.className = 'user';
    el.innerHTML = `${user.name}
${user.email}`; container.appendChild(el); }); } // Fungsi untuk menampilkan status function showStatus(message, error = false) { const status = document.getElementById('status'); status.textContent = message; status.style.color = error ? 'red' : 'green'; } // Fungsi untuk mendapatkan data pengguna function getUsers() { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', 'https://jsonplaceholder.typicode.com/users'); xhr.onload = () => { if (xhr.status === 200) { resolve(JSON.parse(xhr.responseText)); } else { reject('Gagal GET. Status: ' + xhr.status); } }; xhr.onerror = () => reject('Kesalahan jaringan'); xhr.send(); }); } // Fungsi untuk mengirim data pengguna function postUser() { const name = document.getElementById('name').value.trim(); const email = document.getElementById('email').value.trim(); if (!name || !email) return showStatus('Isi semua input!', true); const xhr = new XMLHttpRequest(); xhr.open('POST', 'https://jsonplaceholder.typicode.com/users'); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = () => { if (xhr.status === 201) { const data = JSON.parse(xhr.responseText); showStatus('Berhasil: ' + data.name); } else { showStatus('Gagal POST. Status: ' + xhr.status, true); } }; xhr.onerror = () => showStatus('Kesalahan saat POST.', true); xhr.send(JSON.stringify({ name, email })); } // Memanggil fungsi getUsers dan menangani Promise getUsers() .then(data => showUsers(data)) .catch(err => showStatus(err, true));

3. Fetch

Fetch API merupakan fitur baru sebagai alternatif AJAX. Fetch API menyediakan cara yang lebih modern dan berbasis Promise untuk melakukan request HTTP. Fetch API lebih mudah digunakan dan memiliki sintaks yang lebih bersih dibandingkan XMLHttpRequest.

Contoh Fetch

// Fungsi untuk menampilkan status
function showStatus(message, error = false) {
  const status = document.getElementById('status');
  status.textContent = message;
  status.style.color = error ? 'red' : 'green';
}

// Fungsi untuk menampilkan data pengguna
function showUsers(users) {
  const container = document.getElementById('user-container');
  container.innerHTML = '';
  users.forEach(user => {
    const el = document.createElement('div');
    el.className = 'user';
    el.innerHTML = `${user.name}
${user.email}`; container.appendChild(el); }); } // Fungsi untuk mendapatkan data pengguna function getUsers() { fetch('https://jsonplaceholder.typicode.com/users') .then(res => { if (!res.ok) throw new Error('Status: ' + res.status); return res.json(); }) .then(data => showUsers(data)) .catch(err => showStatus('Gagal GET: ' + err.message, true)); } // Fungsi untuk mengirim data pengguna function postUser() { const name = document.getElementById('name').value.trim(); const email = document.getElementById('email').value.trim(); if (!name || !email) { return showStatus('Nama dan Email harus diisi.', true); } fetch('https://jsonplaceholder.typicode.com/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, email }) }) .then(res => { if (!res.ok) throw new Error('Status: ' + res.status); return res.json(); }) .then(data => showStatus('Berhasil kirim data: ' + data.name)) .catch(err => showStatus('Gagal POST: ' + err.message, true)); } getUsers();

4. Async-Await

Async/await adalah sintaks modern yang dibangun di atas Promise, memungkinkan penulisan kode asynchronous yang lebih bersih dan mudah dibaca. Dengan async/await, kita dapat menulis kode asynchronous seperti kode synchronous, sehingga lebih mudah dipahami.

Contoh Async-Await

// Fungsi untuk menampilkan status
function showStatus(message, error = false) {
  const status = document.getElementById('status');
  status.textContent = message;
  status.style.color = error ? 'red' : 'green';
}

// Fungsi untuk menampilkan data pengguna
function showUsers(users) {
  const container = document.getElementById('user-container');
  container.innerHTML = '';
  users.forEach(user => {
    const el = document.createElement('div');
    el.className = 'user';
    el.innerHTML = `${user.name}
${user.email}`; container.appendChild(el); }); } // Fungsi untuk mendapatkan data pengguna dengan async/await async function getUsers() { try { const res = await fetch('https://jsonplaceholder.typicode.com/users'); if (!res.ok) throw new Error('Status: ' + res.status); const data = await res.json(); showUsers(data); } catch (err) { showStatus('Gagal GET: ' + err.message, true); } } // Fungsi untuk mengirim data pengguna dengan async/await async function postUser() { const name = document.getElementById('name').value.trim(); const email = document.getElementById('email').value.trim(); if (!name || !email) return showStatus('Harap isi semua kolom!', true); try { const res = await fetch('https://jsonplaceholder.typicode.com/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, email }) }); if (!res.ok) throw new Error('Status: ' + res.status); const data = await res.json(); showStatus('Data terkirim: ' + data.name); } catch (err) { showStatus('Gagal POST: ' + err.message, true); } } getUsers();

Perbandingan dan Kasus Penggunaan

Teknologi Kelebihan Kekurangan Kasus Penggunaan
AJAX (XHR) Kompatibilitas luas Callback hell, sintaks verbose Projek lama, browser sangat lama
Promise Menghindari callback hell Masih perlu .then() Operasi berantai, error handling
Fetch API Sintaks modern, berbasis Promise Tidak support browser lama Request HTTP modern
Async/Await Sintaks bersih, mudah dibaca Hanya bekerja dengan Promise Kode async yang kompleks

Kesimpulan

Dalam pengembangan web modern, Fetch API dengan async/await adalah kombinasi yang paling direkomendasikan untuk operasi asynchronous. Namun, memahami semua teknik dari AJAX hingga async/await penting untuk mengatasi berbagai skenario pengembangan dan masalah kompatibilitas.

Mulailah dengan async/await untuk kode yang lebih bersih, tetapi ketahui juga cara kerja Promise dan Fetch API di baliknya. Untuk proyek yang membutuhkan kompatibilitas ekstrem, XMLHttpRequest masih bisa menjadi pilihan, meskipun jarang diperlukan di era modern.