Node.js Ultimate Guide untuk Pemula — Part 2

Serial - Node.js Ultimate Guide untuk Pemula

Sebelum lanjut, pastikan teman-teman sudah mengecek part sebelumnya di sini ya: Node.js Ultimate Guide untuk Pemula — Part 1

This article has been translated into English version: Node.js Ultimate Guide for Beginner — Part 2

Di part ini, kita akan mempelajari bagaimana cara kerja dari Node.js, terutama mengenai konsep callback, Promise, dan async serta await di JavaScript dan bagaimana implementasinya di Node.js.

Alur Sistem Node.js

Node.js sering diistilahkan sebagai sebuah JavaScript runtime yang berjalan secara asynchronous secara event-driven. Asynchronous programming adalah salah satu konsep penting dalam JavaScript yang memungkinkan kita untuk menjalankan beberapa tugas secara bersamaan tanpa harus menunggu tugas-tugas sebelumnya selesai.

Penjelasan tentang Node.js di dokumentasi resmi mereka (Sumber: https://nodejs.org/en/about)
Penjelasan tentang Node.js di dokumentasi resmi mereka (Sumber: https://nodejs.org/en/about)

Jadi berbeda dengan runtime lainnya yang berjalan secara blocking. Artinya, setiap eksekusi dari kode program harus menunggu hingga kode yang lainnya selesai dikerjakan. Berbeda dengan Node.js yang sebagaian besar API-nya sudah didesain secara non-blocking yang mana kode tersebut bisa dijalankan secara bersamaan tanpa harus menunggu kode sebelumnya selesai dikerjakan. Penjelasan lebih lanjut tentang blocking dan non-blocking bisa dibaca di sini.

Sehingga jika digambarkan secara visual, beginilah cara Node.js bekerja.

Alur sistem dari Node.js (Sumber: https://medium.com/@alexchristianqr/arquitectura-de-node-js-conceptos-importantes-de-nivel-senior-f1a5a6d478fd)
Alur sistem dari Node.js (Sumber: https://medium.com/@alexchristianqr/arquitectura-de-node-js-conceptos-importantes-de-nivel-senior-f1a5a6d478fd)

Di gambar tersebut, setiap API punya worker thread-nya masing-masing. Setiap worker thread tersebut akan bekerja secara bersamaan ketika ada permintaan yang masuk dari event loop. Di sinilah event loop memiliki peran yang vital, yaitu untuk menangani setiap permintaan yang masuk ke dalam event queue, menempatkannya di worker thread yang tepat, sekaligus mengembalikan hasil prosesnya ke event queue yang benar.

Jika penjelasan di atas terlalu sulit dipahami, kita bisa memulainya dengan memahami lebih dulu tentang konsep events dan callbacks di Node.js.

Events dan Callbacks

Pertama-tama, mari kita mulai dari callback. Callback adalah fungsi yang dikirim sebagai argumen ke fungsi lain dan akan dieksekusi setelah fungsi tersebut selesai. Nah, di sinilah kekuatan asynchronous muncul: kita bisa menjalankan kode lain sambil menunggu proses asynchronous selesai.

Tapi ada kelemahan dari callback, yaitu yang dikenal dengan callback hell. Ketika kita mulai memanggil banyak callback bersarang, kodenya menjadi sulit dibaca dan dipelihara. Berikut adalah contoh sederhana callback di JavaScript:

javascript

function sayHello(callback) {
  console.log('Hello');
  callback();
}

sayHello(function() {
  console.log('World!');
});

Namun, seperti yang disebutkan, semakin banyak callback yang kita daftarkan, kode akan semakin berantakan.

Promise

Untuk mengatasi masalah ini, muncullah Promise. Promise membantu kita menangani operasi asynchronous dengan lebih rapi dan bersih. Dalam Promise, kita bisa melakukan sesuatu setelah Promise tersebut resolved (berhasil) atau rejected (gagal).

Misalnya, berikut adalah contoh penggunaan Promise:

javascript

const promise = new Promise(function(resolve, reject) {
  const success = true;

  if (!success) {
    return reject('Failure!');
  }
  
  return resolve('Success!');
});

promise.then(function(result) {
  console.log(result); // Success!
}).catch(function(error) {
  console.log(error); // Failure!
});

Dengan Promise, kita bisa menghindari callback hell karena kita bisa menggunakan method .then() untuk menangkap hasil dari Promise ketika berhasil, dan .catch() untuk menangkap jika terjadi error.

Namun, ada hal yang perlu diingat: kalau kita hanya mengembalikan Promise tanpa menangani hasilnya, kita hanya akan mendapatkan objek Promise tanpa hasil yang diinginkan. Agar hasilnya muncul, kita perlu memanggil then seperti pada contoh di atas.

Async/Await

Nah, async dan await adalah penyempurnaan dari Promise dan membuat kode asynchronous jauh lebih mudah dibaca. Dengan async/await, kita tidak perlu lagi membuat banyak method .then() untuk menangani hasil dari Promise. Sebagai gantinya, kita tinggal menambahkan keyword await di depan Promise yang kita panggil, dan hasilnya langsung disimpan dalam variabel.

Contoh penggunaan async/await:

javascript

async function fetchData() {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  
  console.log(data);
}

fetchData();

Apa yang terjadi di sini? Dengan menggunakan await, kita membuat kode seolah-olah “menunggu” hasil dari fetch API tadi sebelum melanjutkan ke baris selanjutnya. Tapi tenang saja, meski terlihat seperti synchronous, ini tetap asynchronous di balik layar. Karena itu, kita harus selalu membungkus kode yang menggunakan await dalam fungsi yang diawali dengan keyword async.

Dan satu hal yang perlu diingat, async function akan selalu mengembalikan Promise. Artinya, meski kita tidak secara eksplisit menuliskan return new Promise(), function tersebut secara otomatis menghasilkan Promise.

Implementasi di Node.js

Mari kita ambil contoh sederhana tentang cara menggunakan async/await dalam proyek Node.js.

javascript

async function main() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    
    console.log(data);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
}

main();

Dalam kode di atas, kita membungkus fetch dan response.json() dengan await, sehingga kita tidak perlu menggunakan .then() lagi. Ini membuat kode lebih bersih dan lebih mudah dipahami.

Penutup

Jadi, itulah sekilas tentang asynchronous di JavaScript. Mulai dari callback, Promise, hingga async/await, semuanya memiliki peran masing-masing dalam membuat kode asynchronous lebih efisien dan mudah dibaca. Jika kamu baru mulai belajar, pahami dulu konsep dasarnya dan jangan khawatir jika terasa rumit di awal. Dengan latihan, kamu pasti akan terbiasa dan lebih paham.

Di part selanjutnya, kita akan mencoba mempelajari cara membuat sebuah projek Node.js dengan npm init, mem-push-nya ke GitHub, lalu men-deploy-nya ke Render. Jika ada topik lain seputar Node.js yang ingin kita bahas bersama, jangan sungkan untuk menulis pendapatmu di kolom komentar ya! Terima kasih.


Sumber

Konten Terkait