Cara menggunakan ASYNCONOUS pada JavaScript

Proses asynchronous sering digunakan untuk komunikasi data, karena data menjadi bagian inti dari sebuah aplikasi maka konsep asynchronous sangat penting untuk dipahami.


Single Threaded

Selain termasuk Interpreted Language dan Dynamic-Typed Language, JavaScript juga termasuk Single Threaded Programming Language.

Yaitu JavaScript hanya bisa melakukan satu operasi di satu waktu, sehingga code JavaScript dieksekusi secara berurutan dari atas ke bawah layaknya sebuah antrian atau biasa disebut synchronous.

1console.log('Hi Brachio');

2

3console.log('the time has come');

4

5console.log('to learn how to code');

Cara menggunakan ASYNCONOUS pada JavaScript

Namun hal ini bisa menjadi masalah jika terdapat code yang eksekusinya membutuhkan waktu yang lama, seperti code untuk mendownload data dari server.

Kita tidak tahu berapa lama waktu yang dibutuhkan untuk download data tersebut.

Jika mengikuti mekanisme synchronous dimana JavaScript hanya bisa melakukan satu operasi di satu waktu maka seharusnya JavaScript akan berhenti dan tidak akan mengeksekusi code selanjutnya sebelum download selesai.

Kenyataannya kita masih bisa melakukan aktifitas browsing meskipun download sedang berlangsung dan browser tidak hang.

Cara menggunakan ASYNCONOUS pada JavaScript

Bagaimana JavaScript bisa melakukannya?

Jawabannya adalah JavaScript melakukannya secara asynchronous.

Pada konsep asynchronous, code akan dieksekusi tanpa menunggu eksekusi code lain selesai sehingga seakan-akan dieksekusi secara bersamaan.

Kita bisa menggunakan simulasi berikut:

1console.log('Hi Brachio');

2

3setTimeout(function () {

4 console.log('the time has come');

5}, 3000);

6

7console.log('to learn how to code');

setTimeout pada code di atas membuat kata the time has come akan ditampilkan setelah 3 detik.

Namun JavaScript tidak akan menunggu selama 3 detik tapi akan segera menampilkan kata to learn how to code.

Sehingga hasilnya:

1Hi Brachio

2to learn how to code

3the time has come

Berikut gambaran perbedaan antara synchronous, asynchronous, dan asynchronous pada javascript:

Synchronous

Cara menggunakan ASYNCONOUS pada JavaScript

Asynchronous

Cara menggunakan ASYNCONOUS pada JavaScript

Asynchronous pada JavaScript

Cara menggunakan ASYNCONOUS pada JavaScript

Event Loop

Untuk lebih memahami asynchronous pada JavaScript kita perlu mengetahui apa itu Event Loop.

Event loop adalah bagian dari JavaScript Runtime yang bertugas untuk menangani Event Callback, Event Callback sendiri adalah bagian dari code yang dieksekusi setelah event tertentu.

Contoh Kasus: Klik tombol Download di browser.

  • mouse click adalah event
  • function yang bertugas untuk mengunduh adalah callback

Ketika event terjadi maka callback dari event tersebut akan ditempatkan pada suatu tempat yang disebut Event Handler Queue atau Queue.

Event Loop akan terus memonitor Queue dan akan mengeksekusi callback sesuai urutan siapa yang pertama masuk ke dalam Queue.

Cara menggunakan ASYNCONOUS pada JavaScript

Ada 3 teknik yang digunakan untuk menghandle proses asynchronous pada JavaScript:

  1. Callback
  2. Promise
  3. Async Await

Callback JavaScript

Callback adalah function yang menjadi argument untuk function lain dan akan dieksekusi pada poin tertentu, bisa jadi saat ini atau nanti.

Contoh

1const notify = () => {

2 console.log('Download complete!');

3};

4

5const download = (url, callback) => {

6 console.log(`Downloading from ${url}....`);

7

8 callback();

9};

10

11const url = 'https://brachio.site/download';

12

13download(url, notify);

Cara menggunakan ASYNCONOUS pada JavaScript

Output dari code di atas adalah:

1Downloading from https://brachio.site/download....

2Download complete!

Pada code di atas function notify adalah callback function, dipanggil setelah code console.log(Downloading from \${url}....);.


💡 INFO

Menjadikan function sebagai argument untuk function yang lain adalah sesuatu yang mungkin di JavaScript, karena function pada JavaScript adalah First-Class Object.

Yang berarti function memiliki karakter yang sama dengan object.

Sehingga sebuah function dapat:

  • disimpan dalam sebuah variable, object atau array
  • menjadi argument untuk function lain (High-Order Function)
  • menghasilkan function baru

Nested Callback

Kita bisa menambahkan callback di dalam callback.

1const download = (url, callback) => {

2 console.log(`Downloading from ${url}....`);

3

4 callback();

5};

6

7const url1 = 'https://brachio.site/download';

8const url2 = 'https://trex.site/download';

9const url3 = 'https://stego.site/download';

10

11download(url1, function () {

12 download(url2, function () {

13 download(url3, function () {

14 console.log('Download complete!');

15 });

16 });

17});

Code di atas dieksekusi tanpa error dan menghasilkan ouput yang sesuai dengan perkiraan.

1Downloading from https://brachio.site/download....

2Downloading from https://trex.site/download....

3Downloading from https://stego.site/download....

4Download complete!

Namun kondisi ini bisa mengarah ke suatu masalah yang disebut dengan Callback Hell, yaitu kondisi dimana terlalu banyak callback di dalam callback yang lain.

Callback Hell membuat code sulit untuk dipahami dan sulit diperbaiki jika ditemukan bug di dalamnya.

Sebagai gantinya kita bisa menggunakan Promise.

Promise

Promise bisa dikatakan sebagai object yang menyimpan hasil dari sebuah operasi asynchronous baik itu hasil yang diinginkan (resolved value) atau alasan kenapa operasi itu gagal (failure reason).

Kita ambil contoh seperti saat kita memesan ojek online.

Saat kita mencari driver lewat aplikasi, aplikasi akan berjanji(promise) memberi tahu hasil dari pencarian kita.

Hasilnya bisa diantara dua, yaitu driver ditemukan (resolved value) atau alasan kenapa driver tidak ditemukan(failure reason).

Sebuah Promise berada di salah satu diantara 3 kondisi(state):

  • pending, operasi sedang berlangsung
  • fulfilled, operasi selesai dan berhasil
  • rejected, operasi selesai namun gagal

Sama seperti pada kasus memesan ojek online, status permintaan kita pada aplikasi online diantara tiga kondisi:

  • Mencari driver (pending)
  • Menemukan driver (fulfilled)
  • Driver tidak ditemukan (rejected)

Membuat Promise

Keyword yang dipakai untuk membuat Promise adalah Promise.

1let progress = 100;

2

3const download = new Promise((resolve, reject) => {

4 if (progress === 100) {

5 resolve('Download complete');

6 } else {

7 reject('Download failed');

8 }

9});

Function setelah keyword new Promise disebut executor.

Dan di dalam executor terdapat dua callback function:

  • resolve(value) adalah callback function yang dieksekusi jika operasi yang dijalankan oleh executor berhasil(fulfilled)
  • reject(error) adalah callback function yang akan dieksekusi jika operasi gagal (rejected)

Promise Handler

Selanjutnya untuk merespon hasilnya (baik berupa value atau error) kita perlu menambahkan handler.

Handler biasanya berupa function dan ditempatkan di dalam method bernama then().

1download.then((result, error) => {

2 console.log(result);

3 console.log(error);

4});

sedangkan untuk merespon error kita bisa tambahkan method catch().

1download

2 .then((result) => {

3 console.log(result);

4 })

5 .catch((error) => {

6 console.log(error);

7 });

Promise Chaining

Karena output dari method then() dan catch() adalah sebuah Promise, maka kita bisa merangkainya(chain) dengan Promise yang lain.

1let initProgress = 0;

2

3const download = new Promise((resolve, reject) => {

4 let progress = initProgress + 25;

5 resolve(progress);

6});

7

8download

9 .then((result) => {

10 console.log(`Download progress is ${result}%`);

11 return result + 25;

12 })

13 .then((result) => {

14 console.log(`Download progress is ${result}%`);

15 return result + 50;

16 })

17 .then((result) => {

18 if (result === 100) {

19 console.log('Download complete');

20 }

21 });

Promise.all()

Method Promise.all() digunakan untuk mengeksekusi Promise secara paralel.

Output dari Promise.all() adalah sebuah promise.

1const downloadStart = new Promise((resolve, reject) => {

2 resolve('0%');

3});

4const downloadHalf = new Promise((resolve, reject) => {

5 resolve('50%');

6});

7const downloadFull = new Promise((resolve, reject) => {

8 resolve('100%');

9});

10

11Promise.all([downloadStart, downloadHalf, downloadFull]).then((result) => {

12 console.log(result);

13});

Callback vs Promise

Seperti yang disebutkan sebelumnya bahwa kita bisa menggunakan promise untuk mengatasi masalah callback hell.

Callback Hell

1const download = (url, callback) => {

2 console.log(`Downloading from ${url}....`);

3

4 callback();

5};

6

7const url1 = 'https://brachio.site/download';

8const url2 = 'https://trex.site/download';

9const url3 = 'https://stego.site/download';

10

11download(url1, function () {

12 download(url2, function () {

13 download(url3, function () {

14 console.log('Download complete!');

15 });

16 });

17});

✔️ Promise

1const download = (url) => {

2 return new Promise((resolve, reject) => {

3 resolve(`Downloading from ${url}....`);

4 });

5};

6

7const url1 = 'https://brachio.site/download';

8const url2 = 'https://trex.site/download';

9const url3 = 'https://stego.site/download';

10

11Promise.all([download(url1), download(url2), download(url3)]).then((result) => {

12 for (let downloadInfo of result) {

13 console.log(downloadInfo);

14 }

15 console.log('Download Complete');

16});

💡 Callback adalah function dan Promise adalah object

Async Await

Async/Await diperkenalkan di ES8 / ES2017 untuk menghandle operasi asynchronous dengan syntax yang lebih mirip dengan synchronous.

Async/Await sendiri dibuat di atas Promise.

Kita bisa membuat simulasi proses download menggunakan code dibawah ini.

1const getStatus = (url) => {

2 console.log(`Downloading from ${url}...`);

3

4 return new Promise((resolve, reject) => {

5 setTimeout(() => {

6 resolve('Download Complete');

7 }, 3000);

8 });

9};

10

11async function download(url) {

12 let status = await getStatus(url);

13 console.log(status);

14}

15

16const url = 'https://brachio.site/download';

17

18download(url);

Pada code di atas keyword await membuat function download harus menunggu sampai function getStatus() selesai dieksekusi.

❗ Keyword await harus berada di dalam function async

Promise vs Async Await

Sekarang mari kita update code sebelumnya yang menggunakan Promise menjadi menggunakan Async/Await.

Promise

1const download = (url) => {

2 return new Promise((resolve, reject) => {

3 resolve(`Downloading from ${url}....`);

4 });

5};

6

7const url1 = 'https://brachio.site/download';

8const url2 = 'https://trex.site/download';

9const url3 = 'https://stego.site/download';

10

11Promise.all([download(url1), download(url2), download(url3)]).then((result) => {

12 for (let downloadInfo of result) {

13 console.log(downloadInfo);

14 }

15 console.log('Download Complete');

16});

Async/Await

1const download = (url) => {

2 return new Promise((resolve, reject) => {

3 resolve(`Downloading from ${url}....`);

4 });

5};

6

7const url1 = 'https://brachio.site/download';

8const url2 = 'https://trex.site/download';

9const url3 = 'https://stego.site/download';

10

11async function runDownload() {

12 let result1 = await download(url1);

13 console.log(result1);

14

15 let result2 = await download(url2);

16 console.log(result2);

17

18 let result3 = await download(url3);

19 console.log(result3);

20

21 console.log('Download Complete');

22}

23

24

25runDownload();

Kita juga bisa menggunakan arrow function.

1const download = (url) => {

2 return new Promise((resolve, reject) => {

3 resolve(`Downloading from ${url}....`);

4 });

5};

6

7const url1 = 'https://brachio.site/download';

8const url2 = 'https://trex.site/download';

9const url3 = 'https://stego.site/download';

10

11const runDownload = async () => {

12 let result1 = await download(url1);

13 console.log(result1);

14

15 let result2 = await download(url2);

16 console.log(result2);

17

18 let result3 = await download(url3);

19 console.log(result3);

20

21 console.log('Download Complete');

22};

23

24

25runDownload();

Apa itu asynchronous JavaScript?

Jawabannya adalah JavaScript melakukannya secara asynchronous. Pada konsep asynchronous, code akan dieksekusi tanpa menunggu eksekusi code lain selesai sehingga seakan-akan dieksekusi secara bersamaan. setTimeout pada code di atas membuat kata the time has come akan ditampilkan setelah 3 detik.

Kapan menggunakan asynchronous?

Kapan Menggunakan Async? Pemanfaatan async sangat berguna pada saat melakukan operasi-operasi yang tidak harus menunggu proses yang lainnya. Misalnya, memanipulasi DOM ketika melakukan proses ajax . Agar bisa memahami, kita perlu mengetahui cara menghandle kode async tersebut dengan cara callback ataupun promises .

Fungsi async untuk apa?

Asynchronous network server programming adalah sebuah pendekatan dalam komunikasi server dimana server dapat saling berkomunikasi, mengirim, dan menerima data dengan bersamaan tanpa harus menghentikan komunikasi dengan client lain.

Apa itu Await di JS?

Keyword await membuat JavaScript menunggu sampai promise tersebut selesai dan mengembalikkan hasilnya.