
Pernah membuka aplikasi yang tiba-tiba berhenti merespons saat memuat data? Masalah tersebut bisa terjadi ketika aplikasi harus menunggu proses yang membutuhkan waktu cukup lama. Contohnya, mengambil data dari server, membaca file, atau mengirim permintaan ke API.
Dalam pengembangan web, async programming JavaScript membantu menangani proses tersebut tanpa membuat aplikasi berhenti merespons. Melalui pendekatan ini, program dapat melanjutkan pekerjaan lain sambil menunggu proses tertentu selesai. Lalu, bagaimana cara kerjanya? Mari kenali konsep asynchronous programming, mulai dari dasar hingga contoh penerapannya.
Apa Itu Async Programming dalam JavaScript?
Async programming atau asynchronous programming merupakan teknik pemrograman yang memungkinkan aplikasi menangani proses tanpa harus menunggu setiap pekerjaan selesai secara berurutan. JavaScript umumnya menjalankan kode menggunakan satu main thread. Artinya, satu proses JavaScript dieksekusi pada satu waktu di thread tersebut. Meskipun demikian, aplikasi tidak harus berhenti ketika menunggu proses yang lambat.
Melalui lingkungan runtime seperti browser atau Node.js, JavaScript dapat menangani operasi tertentu secara asynchronous. Selama proses tersebut berlangsung, program tetap bisa menjalankan tugas lain. Sebagai contoh, ketika aplikasi meminta data dari server, pengguna masih bisa berinteraksi dengan halaman sambil menunggu jawaban dari server.
Mengapa JavaScript Membutuhkan Async Programming?
Bayangkan sebuah aplikasi yang harus mengambil data dari server sebelum menampilkan halaman. Jika seluruh proses berjalan secara berurutan, pengguna mungkin harus melihat layar kosong selama beberapa detik. Situasi tersebut tentu dapat mengurangi kenyamanan saat menggunakan aplikasi.
Async programming menawarkan beberapa solusi untuk mengatasi masalah tersebut.
- Menjaga aplikasi tetap responsif. Pengguna masih bisa berinteraksi dengan aplikasi saat proses jaringan berlangsung.
- Mengelola permintaan data. Developer dapat menangani permintaan ke API tanpa harus menghentikan alur utama.
- Meningkatkan pengalaman pengguna. Aplikasi bisa menampilkan indikator loading selama menunggu data.
- Mengatur proses yang saling berkaitan. Program dapat menentukan tindakan setelah proses berhasil atau mengalami kegagalan.
Karena manfaat tersebut, asynchronous programming menjadi salah satu konsep penting dalam pengembangan aplikasi web modern.
Memahami Cara Kerja Event Loop JavaScript
Untuk memahami async programming, developer perlu mengenal event loop. Mekanisme ini membantu JavaScript mengatur eksekusi kode asynchronous.
Ada tiga komponen utama yang perlu dipahami.
1. Call Stack
Call stack merupakan tempat JavaScript mengatur fungsi yang sedang berjalan. Ketika program memanggil sebuah fungsi, JavaScript memasukkan fungsi tersebut ke dalam call stack. Setelah fungsi selesai, sistem mengeluarkannya dari stack.
2. Task Queue
Task queue menyimpan tugas asynchronous yang sudah siap untuk dieksekusi. Salah satu contohnya adalah callback dari setTimeout. Setelah waktu tunggunya selesai, callback tersebut masuk ke antrean tugas.
3. Event Loop
Event loop memantau call stack dan antrean tugas. Ketika call stack kosong, mekanisme ini membantu menjalankan tugas yang sudah siap. JavaScript juga memiliki microtask queue selain task queue. Promise menggunakan antrean microtask untuk menjalankan callback seperti .then() dan .catch().
Microtask biasanya berjalan lebih dahulu daripada task berikutnya setelah kode yang sedang berjalan selesai.
Melalui mekanisme tersebut, JavaScript dapat mengatur pekerjaan asynchronous tanpa harus menghentikan seluruh aplikasi.
3 Cara Menangani Proses Asynchronous di JavaScript
JavaScript menyediakan beberapa pendekatan untuk mengelola proses asynchronous. Berikut tiga konsep yang sering digunakan developer.
1. Callback
Callback adalah fungsi yang dikirim sebagai argumen ke fungsi lain. Program akan menjalankan callback tersebut ketika suatu proses mencapai kondisi tertentu. Berikut contoh sederhananya:
setTimeout(() => {
console.log("Proses selesai!");
}, 2000);
console.log("Aplikasi tetap berjalan");Pada contoh tersebut, setTimeout() menjadwalkan fungsi untuk berjalan setelah sekitar dua detik. Sementara itu, JavaScript langsung menjalankan perintah console.log() berikutnya.
Hasilnya:
Aplikasi tetap berjalan
Proses selesai!
Artinya, JavaScript tidak perlu menunggu dua detik sebelum menjalankan perintah selanjutnya.
Namun, penggunaan callback yang terlalu bertingkat dapat membuat kode sulit dibaca. Developer sering menyebut kondisi tersebut sebagai callback hell.
2. Promise
Promise merupakan objek JavaScript yang mewakili hasil dari proses asynchronous. Terdapat tiga status utama dalam Promise:
- Pending: Proses masih berjalan.
- Fulfilled: Proses berhasil.
- Rejected: Proses mengalami kegagalan.
Contoh penggunaan Promise:
const ambilData = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data berhasil diterima!");
}, 2000);
});
ambilData
.then((hasil) => {
console.log(hasil);
})
.catch((error) => {
console.log(error);
});Dalam contoh tersebut, Promise menunggu proses selama dua detik. Setelah selesai, fungsi resolve() mengirim hasil yang berhasil. Selanjutnya, .then() menangani hasil tersebut. Jika proses gagal, .catch() dapat menangani kesalahannya.
3. Async/Await
Async/await merupakan cara yang lebih sederhana untuk menulis kode asynchronous berbasis Promise. Pendekatan ini membuat alur kode terlihat lebih mirip dengan kode synchronous. Namun, prosesnya tetap menggunakan mekanisme asynchronous. Perhatikan contoh berikut:
function ambilData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Data berhasil diterima!");
}, 2000);
});
}
async function tampilkanData() {
console.log("Mengambil data...");
const hasil = await ambilData();
console.log(hasil);
}
tampilkanData();
console.log("Aplikasi tetap berjalan");Kata kunci async menandai sebuah fungsi sebagai fungsi asynchronous. Sementara itu, await menangguhkan kelanjutan fungsi tersebut sampai Promise menghasilkan nilai. Perlu diingat, await tidak menghentikan seluruh aplikasi. Kode lain di luar fungsi tersebut tetap bisa berjalan.
Developer juga dapat menggunakan try...catch untuk menangani kesalahan.
async function tampilkanData() {
try {
const hasil = await ambilData();
console.log(hasil);
} catch (error) {
console.log("Terjadi kesalahan:", error);
}
}Melalui pendekatan ini, kode asynchronous menjadi lebih mudah dibaca dan dikelola.
Contoh Penerapan Async Programming dalam Aplikasi Web
Salah satu penerapan async programming yang paling umum adalah mengambil data dari API menggunakan fetch().
Sebagai contoh, sebuah aplikasi ingin mengambil daftar pengguna dari server.
async function tampilkanPengguna() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users"
);
if (!response.ok) {
throw new Error("Gagal mengambil data");
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log("Terjadi kesalahan:", error.message);
}
}
tampilkanPengguna();Berikut tahapan yang terjadi dalam kode tersebut:
- Fungsi
tampilkanPengguna()berjalan secara asynchronous. fetch()mengirim permintaan ke server.awaitmenunggu respons dari server tanpa memblokir main thread.response.json()membaca data dalam format JSON.console.log()menampilkan hasil ke console.- Blok
catchmenangani kesalahan jika proses mengalami kegagalan.
Contoh tersebut memperlihatkan bagaimana JavaScript menangani permintaan data tanpa harus menghentikan seluruh aktivitas aplikasi.
