BAB 6 – Asynchronous Programming di Node.js: Callback, Promise, dan Async/Await

BAB 6 – Asynchronous Programming di Node.js: Callback, Promise, dan Async/Await

Node.js dirancang untuk menangani banyak proses tanpa harus menunggu satu proses selesai terlebih dahulu. Inilah alasan mengapa asynchronous programming menjadi konsep inti dalam Node.js.

Secara sederhana, asynchronous berarti:

  • Node.js bisa menjalankan tugas lain
  • tanpa menunggu satu tugas selesai
  • sehingga aplikasi tetap responsif

Tanpa pemahaman async, aplikasi Node.js akan mudah melambat atau bahkan berhenti saat menangani banyak request.


Callback: Cara Async Paling Dasar

Callback adalah function yang dijalankan setelah suatu proses selesai. Ini adalah pola async paling awal yang digunakan di Node.js.

Contoh Callback Sederhana

function getData(callback) {
  setTimeout(() => {
    callback("Data berhasil diambil");
  }, 1000);
}

getData((result) => {
  console.log(result);
});

Callback masih banyak ditemukan, terutama di kode lama atau built-in module tertentu.


Masalah Callback: Callback Hell

Jika callback digunakan berlapis-lapis, kode akan sulit dibaca.

getData((data) => {
  processData(data, (result) => {
    saveData(result, () => {
      console.log("Selesai");
    });
  });
});

Struktur seperti ini sering disebut callback hell dan menjadi alasan munculnya Promise.


Promise: Solusi yang Lebih Rapi

Promise memperkenalkan cara baru menangani async dengan struktur yang lebih jelas.

Contoh Promise

function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Data berhasil diambil");
    }, 1000);
  });
}

Menggunakannya:

getData()
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error(error);
  });

Promise membuat alur async lebih mudah dibaca dibandingkan callback bersarang.


Async/Await: Cara Paling Nyaman

async/await adalah cara paling populer dan paling mudah dipahami saat ini.

Contoh Async/Await

async function loadData() {
  const data = await getData();
  console.log(data);
}

loadData();

Dengan async/await, kode async terlihat seperti kode sinkron, tetapi tetap berjalan secara non-blocking.


Menangani Error pada Async/Await

Error handling pada async/await dilakukan dengan try...catch.

async function loadData() {
  try {
    const data = await getData();
    console.log(data);
  } catch (error) {
    console.error("Terjadi kesalahan:", error.message);
  }
}

Pola ini sangat penting agar aplikasi tidak berhenti tiba-tiba saat terjadi error.


Contoh Praktik: Async dengan File System

import { readFile } from "fs/promises";

async function readData() {
  const data = await readFile("data.txt", "utf-8");
  console.log(data);
}

readData();

Contoh ini menunjukkan penggunaan async/await dalam kasus nyata membaca file.


Menggabungkan Beberapa Async Task

Kadang kita perlu menjalankan beberapa proses async sekaligus.

async function loadAll() {
  const result1 = getData();
  const result2 = getData();

  const data = await Promise.all([result1, result2]);
  console.log(data);
}

loadAll();

Pendekatan ini lebih efisien dibandingkan menjalankan proses satu per satu.


Kesalahan Umum dalam Asynchronous Programming

Beberapa kesalahan yang sering terjadi:

  • lupa menggunakan await
  • tidak menangani error
  • mencampur callback dan async/await

Biasakan memilih satu pola (async/await) agar kode tetap konsisten dan mudah dirawat.


Kapan Harus Menggunakan Callback, Promise, atau Async/Await

Panduan sederhana:

  • Callback → kode lama atau API tertentu
  • Promise → dasar async modern
  • Async/Await → pilihan utama untuk aplikasi baru

Untuk proyek Node.js modern, async/await adalah pilihan terbaik.


Kesimpulan

Asynchronous programming adalah jantung Node.js. Dengan memahami callback, Promise, dan async/await, kita bisa:

  • menulis kode yang lebih rapi
  • menangani banyak proses tanpa macet
  • membangun aplikasi backend yang responsif

Tanpa pemahaman async, Node.js tidak akan bekerja optimal.