Select Page

Pertama coba lihat code berikut terutama bagian output :

main();

function main() {
  console.log('main Begin');

  call(function () {console.log('Callback 1');});

  //Call callback after 0 miliseconds.
  setTimeout(function () {console.log('Callback 2')}, 0);

  console.log('Long running process begin');
  longRunningProcess();
  console.log('Long running process end');

  console.log('main End');

  function call(cb) {cb();}
  function longRunningProcess(){for (var i = 0; i < 1000000000; i++);} 
} 

//Output: 
//main Begin 
//Callback 1 
//Long running process begin 
//Long running process end 
//main End 
//Callback 2 

Sekali lagi, coba perhatikan bagian output (itu adalah output dari program).

//Output: 
//main Begin 
//Callback 1 
//Long running process begin 
//Long running process end 
//main End 
//Callback 2 

Pada code di atas dapat dilihat bahwa script pada Javascript akan dijalankan secara synchronous (sync), ini disebabkan karena eksekusi script hanya dilakukan oleh single thread. Tetapi, coba lihat kembali pada setTimeout, bukankah kita set 0 miliseconds, tetapi kenapa Callback 2 dipanggil terakhir?

//Call callback after 0 miliseconds.                                                              
setTimeout(function () {console.log('Callback 2')}, 0);

Seharusnya pada bagian output terprint Callback 1 lalu Callback 2.
Tapi yang terjadi setelah terprint Callback 1 eksekusi berlanjut ke Long running process. Callback 2 malah terprint di akhir?
Itu karena walaupun eksekusi script di Javasript dilakukan secara sync tetapi Javascript punya yang namanya Event Loop.

0_1452096702987_e1.png
Gambar di atas merepresentasikan queue dari message (Message’s queue).

Jadi, apa yang sebenarnya terjadi ?
Pada saat control memanggil main(), maka Javascript runtime akan menambahkannya ke dalam queue. Sementara di bagian lain dari runtime, Event Loop secara berulang melakukan pekerjaannya. Event Loop akan terus berputar memeriksa queue, apakah ada Message baru yang siap untuk diproses. Untuk setiap satu putaran biasa disebut tick. Ketika Event Loop mendapatkan bahwa kini queue sudah berisi Message 1, maka Event Loop akan memproses Message 1 tersebut.

0_1452096702987_e1.png

Di dalam Message 1, main() dipanggil dan kemudian script di dalam main() dieksekusi dengan urutan sebagai berikut :

  1. call(function () {console.log('Callback 1');});
  2. setTimeout(function () {console.log(‘Callback 2’)}, 0);
  3. longRunningProcess();

Eksekusi script berjalan secara sync. Jadi ketika call dipanggil maka Callback 1 langsung dieksekusi yang menyebabkan Callback 1 terprint di Console. Kemudian control memanggil setTimeout, yang seharusnya akan memanggil Callback 2 setelah 0 miliseconds.

Ini menarik karena setTimeout tidak langsung memanggil Callback 2, yang menyebabkan Callback 2 seolah-olah dipanggil secara async.

Yang terjadi sebenarnya adalah, ketika control memanggil setTimeout, maka Event Loop sebenarnya memerintahkan runtime untuk memanggil Callback 2 setelah 0 miliseconds. Setelah itu setTimeout selesai dan control berlanjut ke line berikutnya.
Di sisi lain setelah 0 miliseconds, maka runtime akan memasukkan Message baru ke dalam queue yang kita sebut sebagai Message 2.
Di sini dapat dilihat bahwa sebenarnya Javascript engine memiliki beberapa thread untuk beroperasi. Satu thread disediakan khusus untuk Event Loop, sementara bagian lain dari runtime dijalankan oleh thread-thread yang lain.

0_1452096720441_e2.png

Setelah setTimeout selesai dieksekusi maka control selanjutnya beralih ke longRunningProcess, lalu script eksekusi akan nampak hang karena terjadi loop yang cukup banyak.

Setelah longRunningProcess selesai dieksekusi, maka berarti main() juga selesai dieksekusi dan menyebabkan Message 1 dihapus dari queue.

0_1452096731880_e3.png

Di sini 1 putaran Event Loop selesai. Dan kini Event Loop bersiap melakukan putaran berikutnya, yaitu memeriksa queue apakah ada Message yang siap untuk diproses.

Karena di queue masih ada 1 Message yang tersisa yaitu Message 2 , maka Event Loop pun akan memproses Message 2 tersebut, yang menyebabkan Callback 2 terprint di Console.

0_1452096746708_e4.png

Sampai di sini, Event Loop sudah menyelesaikan putaran keduanya, dan bersiap untuk melakukan putaran berikutnya, yaitu memeriksa queue apakah ada Message yang siap untuk diproses.

Tetapi kini queue sudah kosong sehingga Event Loop hanya akan terus berputar, sambil memeriksa apakah ada Message baru yang memasuki queue.

Bagaimana pendapat agan-agan? Silahkan berikan komentarnya 🙂

References :

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
  2. http://ejohn.org/blog/how-javascript-timers-work
  3. http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained
%d bloggers like this: