JavaScript secara default adalah bahasa single-threaded, artinya hanya dapat menjalankan satu perintah dalam satu waktu.
Namun, dunia web modern sangat membutuhkan asynchronous execution, agar proses seperti request server, animasi, atau event user tidak memblokir eksekusi kode lainnya.
Contents
Sinkron vs Asinkron
Synchronous (Sinkron)
- Eksekusi kode berjalan baris per baris.
- Baris berikutnya menunggu baris sebelumnya selesai.
Contoh:
console.log("A");
console.log("B");
console.log("C");
Output:
A
B
C
Asynchronous (Asinkron)
- Eksekusi kode tidak harus menunggu baris sebelumnya selesai.
- Digunakan untuk operasi yang memakan waktu lama, seperti request API, setTimeout, atau event listener.
Contoh:
console.log("A");
setTimeout(() => console.log("B"), 1000);
console.log("C");
Output:
A
C
B
Penjelasan: setTimeout dijalankan di event loop dan dikirim ke task queue, sehingga kode berikutnya tetap berjalan terlebih dahulu.
💡 Insight baru: Memahami sinkron vs asinkron adalah dasar untuk mencegah race condition dan bug saat bekerja dengan data eksternal.
Event Loop Lanjutan
Event loop adalah mekanisme yang memungkinkan JavaScript menangani asynchronous task tanpa menghentikan eksekusi kode utama.
Cara Kerja:
- JavaScript mengeksekusi kode synchronous terlebih dahulu.
- Task asynchronous (callback, promise, timer) dimasukkan ke queue.
- Event loop mengecek stack:
- Jika stack kosong → ambil task dari queue → eksekusi.
Contoh:
console.log("Start");
setTimeout(() => console.log("Timeout 1"), 0);
Promise.resolve().then(() => console.log("Promise 1"));
console.log("End");
Output:
Start
End
Promise 1
Timeout 1
Penjelasan:
- Promise masuk ke microtask queue, sehingga dieksekusi sebelum macrotask dari
setTimeout.
💡 Insight baru: Event loop adalah alasan mengapa Promise lebih cepat dieksekusi daripada setTimeout meskipun delay 0ms.
Callback Hell
Callback hell terjadi ketika kita menulis callback bertingkat secara berlebihan, sehingga kode menjadi sulit dibaca, dirawat, dan debug.
Contoh callback hell:
loginUser(user, password, function(userData) {
getUserProfile(userData.id, function(profile) {
getUserPosts(profile.id, function(posts) {
console.log(posts);
});
});
});
Masalah:
- Nested callbacks → sulit di-maintain.
- Error handling sulit.
Solusi modern:
- Gunakan Promise:
loginUser(user, password)
.then(userData => getUserProfile(userData.id))
.then(profile => getUserPosts(profile.id))
.then(posts => console.log(posts))
.catch(err => console.error(err));
- Atau gunakan async/await untuk syntax lebih bersih:
async function showPosts() {
try {
const userData = await loginUser(user, password);
const profile = await getUserProfile(userData.id);
const posts = await getUserPosts(profile.id);
console.log(posts);
} catch (err) {
console.error(err);
}
}
showPosts();
💡 Insight baru: Callback hell sering terjadi di proyek lama. Memahami Promise dan async/await adalah kunci pengembangan JavaScript modern.
Microtask vs Macrotask Queue
Event loop memiliki dua jenis queue:
- Macrotask (Task queue)
- Contoh:
setTimeout,setInterval, I/O, event listener. - Dieksekusi setelah synchronous code selesai dan microtask queue kosong.
- Contoh:
- Microtask
- Contoh:
Promise.then,process.nextTick(Node.js),MutationObserver. - Memiliki prioritas lebih tinggi, dieksekusi sebelum macrotask berikutnya.
- Contoh:
Contoh perbedaan:
console.log("Start");
setTimeout(() => console.log("Macrotask 1"), 0);
Promise.resolve().then(() => console.log("Microtask 1"));
Promise.resolve().then(() => console.log("Microtask 2"));
console.log("End");
Output:
Start
End
Microtask 1
Microtask 2
Macrotask 1
💡 Insight baru: Memahami perbedaan microtask dan macrotask membantu developer mengatur urutan eksekusi agar UI tetap responsif dan tidak ada race condition.
Kesimpulan
- JavaScript adalah single-threaded, tapi asynchronous memungkinkan multitasking.
- Sinkron → baris per baris, Asinkron → parallel task.
- Event loop mengatur eksekusi asynchronous dengan stack, microtask, dan macrotask queue.
- Callback hell dapat diatasi dengan Promise dan async/await.
- Microtask selalu dieksekusi sebelum macrotask, memahami ini penting untuk prediksi perilaku kode asynchronous.
💡 Fakta menarik: Banyak masalah performa dan bug pada web modern muncul karena kesalahan memahami event loop, bukan karena logika algoritma. Menguasai asynchronous JavaScript adalah kunci menjadi developer handal.