Asynchronous JavaScript: Pengenalan - Part 1

Annisa NadiaJan 1, 2022 · 6 min read · ___ views
Asynchronous JavaScript: Pengenalan - Part 1

Asynchronous JavaScript kemungkinan besar dipraktekkan dalam membuat aplikasi dengan JavaScript. Konsep ini membantu menangani hal-hal yang membutuhkan waktu yang lebih lama untuk dieksekusi. Misalnya, request data dari API, menghubungkan ke database, dll.

Ini adalah bagian pertama dari seri bahasan mengenai Asynchronous JavaScript. Pada bagian-bagian selanjutnya akan dibahas mengenai callback, promise, serta async & await.

Sebelumnya, kita perlu tau dulu bahwa secara default JavaScript menjalankan kodenya secara synchronous dan single-threaded.

Single-Threaded Language

Thread adalah proses tunggal yang bisa digunakan program untuk menjalankan tasks. Secara default, JavaScript itu single-threaded, artinya cuma bisa menjalankan satu task dalam satu waktu pada single thread (main thread). Setiap task dalam main thread dijalankan secara bertahap.

Pada gambar di bawah, Task 1 dijalankan pertama kali. Setelah Task 1 selesai, maka Task 2 dijalankan, dst.

single thread

Setiap task bisa punya waktu eksekusi yang beda-beda. Misalnya, salah satu task dari gambar di atas, yaitu Task 3, perlu waktu yang lebih lama untuk dieksekusi. Anggap aja kita mau mengambil data dari database sehingga butuh waktu yang lebih lama. Kalau dibutuhkan waktu yang lama, maka Task 3 dapat mem-blocking kode-kode setelahnya.

Blocking Code

Kalau ada potongan kode program yang berjalan secara synchronous dan kode tersebut butuh waktu yang lama untuk dieksekusi, maka kode tersebut dapat menjadi penghalang untuk potongan kode berikutnya, atau dapat disebut blocking code. User bisa mengira programnya berhenti/ freeze karena adanya blocking code. Itulah kenapa potongan kode tertentu perlu dijalankan secara asynchronous sehingga tidak menghalangi kode-kode berikutnya.

Jadi, Asynchronous itu Apa sih?

Sesuatu yang berjalan secara synchronous dilakukan secara bertahap dan sesuai urutan. Task berikutnya belum bisa berjalan kalau task sebelumnya belum selesai dilakukan.

Kebalikan dari synchronous, kalau berjalan secara asynchronous, maka task bisa berjalan tidak bertahap atau tidak sesuai dengan urutan. Untuk menjalankan task berikutnya tidak perlu menunggu task sebelumnya selesai dilakukan.

Ini contoh kode JavaScript yang berjalan secara synchronous. Kalau kode dijalankan, maka huruf a, b, c, dan d ditampilkan secara berurutan.

const a = () => console.log('a');
const b = () => console.log('b');
const c = () => console.log('c');
const d = () => console.log('d');

a();
b();
c();
d();

/*
Output:
a
b
c
d
*/

Ini contoh sederhana konsep asynchronous dengan kode JavaScript.

const a = () => console.log('a');
const b = () => setTimeout(() => console.log('b'), 4000);
const c = () => console.log('c');
const d = () => console.log('d');

a();
b();
c();
d();

/*
Output:
a
c
d
b
*/

Bisa dilihat bahwa kode untuk mencetak huruf b diletakkan dalam suatu callback function. Callback function tersebut merupakan argumen dari fungsi setTimeout() sehingga huruf b baru akan dicetak setelah 4000ms atau 4s.

Fungsi setTimeout() memanggil suatu fungsi setelah beberapa waktu. Fungsi setTimeout() dapat disebut asynchronous karena dapat memutus alur kode yang synchronous, tapi sebenarnya tidak akan dieksekusi pada thread yang terpisah. Fungsi setTimeout() merupakan Web API (pada browser) dan C/C++ API (pada Node.js).

Output dari kode di atas adalah tampilan huruf a, c, d, dan b. Bisa kita lihat, huruf c dan d dicetak lebih dulu tanpa harus menunggu selesainya potongan kode sebelumnya.

Bagaimana Konsep Asynchronous Bisa Bekerja pada JavaScript?

Kode-kode JavaScript dieksekusi di dalam JavaScript Engine. Salah satu bagian dari JavaScript Engine adalah Call Stack. Karena JavaScript itu single-threaded, maka JavaScript cuma punya satu Call Stack.

Seperti struktur data stack pada umumnya, Call Stack menerapkan konsep LIFO (Last in, First out). Kalau suatu fungsi dipanggil, fungsi tersebut akan masuk ke dalam Call Stack. Kalau fungsi sudah me-return suatu nilai atau sudah selesai dieksekusi, maka fungsi tersebut akan keluar dari Call Stack.

Pada contoh kode konsep asynchronous di atas, fungsi a() dipanggil pertama kali, maka fungsi a() masuk ke dalam Call Stack. Fungsi a() dieksekusi dan menjalankan method console.log() sehingga tampil huruf a. Setelah selesai dieksekusi, fungsi a() keluar dari Call Stack.

call stack

Untuk menjalankan kode secara asynchronous, JavaScript Runtime Environment pada browser atau Node.js menyediakan fitur Web API atau C/C++ API, Callback Queue, dan Event Loop. Hal-hal itu bukan bagian dari JavaScript Engine sehingga task bisa dijalankan secara asynchronous di dalam Web API (atau C/C++ API).

call stack, web api, callback queue, event loop

Coba lihat lagi contoh kode konsep asynchronous sebelumnya. Fungsi b() dipanggil setelah fungsi a(), maka fungsi b() masuk ke dalam Call Stack setelah fungsi a() keluar. Fungsi b() dieksekusi dan menjalankan fungsi setTimeout() yang merupakan Web API yang disediakan browser (atau C/C++ API pada Node.js).

Callback function yang merupakan argumen fungsi setTimeout() ditambahkan ke dalam Web API. Timer mulai dijalankan saat callback function ditambahkan ke dalam Web API. Di dalam Call Stack, fungsi setTimeout() dan b() keluar dari Call Stack.

Setelah callback function ditambahkan ke dalam Web API & fungsi b() keluar dari Call Stack, maka fungsi c() bisa masuk ke dalam Call Stack, dieksekusi, menjalankan console.log() sehingga tampil huruf c, kemudian fungsi c() keluar dari Call Stack. Selanjutnya fungsi d() masuk ke dalam Call Stack, dieksekusi, menjalankan console.log() sehingga tampil huruf d, kemudian fungsi d() keluar dari Call Stack.

Setelah timer sudah berjalan sesuai nilai argumen kedua (4000ms) dari fungsi setTimeout(), maka callback function tidak langsung masuk ke dalam Call Stack, tapi dipindahkan dulu ke dalam Callback Queue.

Terdapat Event Loop yang menghubungkan Call Stack dengan Callback Queue. Kalau Call Stack kosong (artinya fungsi-fungsi sebelumnya sudah selesai dieksekusi & keluar dari Call Stack), maka item pertama di dalam Callback Queue ditambahkan ke dalam Call Stack menggunakan Event Loop. Saat berada di dalam Call Stack, callback function dieksekusi, menjalankan console.log() sehingga menampilkan huruf b, kemudian keluar dari Call Stack.

Untuk memvisualisasikan bagaimana Call Stack, Web API, Callback Queue, dan Event Loop saling berinteraksi, bisa coba tulis kode yang diinginkan di situs ini, kemudian jalankan dan lihat hasilnya.

Ya, jadi mungkin cukup untuk bahasan mengenai pengenalan Asynchronous JavaScript. Di artikel-artikel selanjutnya, akan dibahas mengenai callback, promise, serta async & await.

Last updated: Jan 18, 2023Edit on GitHub

Get in Touch

© 2021 - 2024 Annisa Nadia Neyla