JavaScript Di Balik Terpal: Putaran peristiwa

Dec 01 2022
Mari kuasai JavaScript dengan menjelajahi fungsinya dari awal Pernahkah Anda menghadapi kesalahan yang tidak terdefinisi atau kesulitan mengidentifikasi ruang lingkup suatu variabel? Benar-benar memakan waktu untuk men-debug kesalahan apa pun tanpa mengetahui cara kerja kode. Di blog ini, saya akan mendemonstrasikan bagaimana konsep tingkat lanjut seperti loop peristiwa dalam kaitannya dengan konteks eksekusi, tumpukan panggilan, dan antrean panggilan balik benar-benar beroperasi.

Mari kuasai JavaScript dengan menjelajahi fungsinya dari awal

Foto oleh Marc St di Unsplash

Pernahkah Anda menghadapi kesalahan yang tidak terdefinisi atau kesulitan mengidentifikasi ruang lingkup variabel?

Benar-benar memakan waktu untuk men-debug kesalahan apa pun tanpa mengetahui cara kerja kode.

Di blog ini, saya akan mendemonstrasikan bagaimana konsep tingkat lanjut seperti event loopdalam hal execution context, call stack, dan benar- callback queuebenar beroperasi.

Penafian — Konsepnya sangat padat pengetahuan dan saling berhubungan, jadi tolong jangan mengedipkan mata!

Mesin JavaScript

Mesin V8 Google adalah ilustrasi terkenal dari Mesin JavaScript. Misalnya, Chrome dan Node.js menggunakan mesin V8. Pada dasarnya, mesin V8 terdiri dari dua bagian —

  1. Call Stack : Semua kode dijalankan di dalamnya. Ini bekerja seperti struktur data Stack, yang berarti mengikuti konsep LIFO (Last In First Out).
  2. Memory Heap: Di mana alokasi memori terjadi. Berbeda dengan Struktur Data tumpukan, itu hanya memori.

Konteks Eksekusi Global atau GEC adalah Konteks Eksekusi default yang dibuat oleh mesin JavaScript setiap kali file skrip diterima.

Semua kode JavaScript yang tidak ada di dalam fungsi dijalankan dalam GEC. Langkah-langkah berikut dilakukan di GEC

  • Bangun Ruang Memori untuk menyimpan semua variabel dan fungsi dalam skala global
  • Menghasilkan objek global.
  • Menghasilkan kata kuncithis

Tergantung di mana kode Anda akan dieksekusi akan menentukan di mana thisberada. Misalnya, di Node.js menunjuk ke objek global yang berbeda, sedangkan di browser menunjuk ke windowobjek.

Konsol Peramban

Tumpukan Panggilan (Atau Tumpukan Eksekusi Fungsi)

JavaScript adalah single-threaded, seperti yang sudah Anda dengar. Tapi apa sebenarnya artinya?

Ini berarti mesin JavaScript hanya berisi satu call stackatau function execution stack.

  • Seperti yang kita ketahui, setiap kali kompiler pertama kali mengeksplorasi kode Anda, mesin JS diminta untuk membuat Global Execution Contextatau GEColeh kompiler serta diminta untuk menempatkannya ke dalam file Call Stack.
  • Seluruh kode Anda dieksekusi satu per satu di Global Execution Contextdan mengalokasikan memori untuk definisi fungsi atau deklarasi variabel dan menyimpannya di sana.
  • Tetapi ketika pemanggilan fungsi apa pun ditemukan, a Functional Execution Contextor FECdibuat untuk mengeksekusi kode fungsi dan kemudian ditambahkan ke bagian atas call stack.
  • Penerjemah menghapus fungsi dari call stacksetiap kali fungsi berakhir. Fungsi berakhir — saat mencapai akhir ruang lingkupnya atau pernyataan pengembalian.
  • Terakhir, mengeksekusi seluruh kode Anda, GECdihapus dari file Call Stack.

Jangan khawatir, mari kita tunjukkan dengan sebuah contoh.

function f1{
  console.log('f1');
}

f1();
console.log('end');

Langkah 2: — Dalam contoh kita, baris pertama akan dieksekusi yaitu f1. Memori akan dialokasikan untuk f1dan disimpan definisinya.

Langkah 3: — Pada baris ke-2, sebuah fungsi dipanggil. Untuk pemanggilan fungsi ini, a Function Execution Context or FECakan dibuat dan akan disimpan di atas Call Stack.

Langkah 4: — Sekarang, keseluruhan f1()akan dieksekusi baris demi baris dan setelah menyelesaikan eksekusi, keseluruhan akan dihapus dari file Call Stack.

Langkah 5: — Kemudian, baris terakhir console.log('end')akan dieksekusi dan akan mencetak 'akhir' di konsol. Terakhir, mengeksekusi seluruh kode Anda, Global Execution Contextakan dihapus dari file Call Stack.

Bagaimana JS mengelola tugas asinkron?

JavaScript, seperti yang kita semua ketahui, adalah bahasa utas tunggal yang sinkron (satu tugas pada satu waktu), dan utas tunggal yang segera mengeksekusi apa pun yang ada di dalamnya.call stack

Tetapi bagaimana jika kita perlu mengeksekusi sesuatu setelah 5 detik? Bisakah kita melakukannya di dalam call stack?

Tidak, kami tidak bisa. Karena call stacktidak memiliki timer apapun. Tapi bagaimana kita bisa melakukan itu?

Di sinilah runtime JavaScript masuk.

Lingkungan Waktu Proses JavaScript

Sungguh menyedihkan jika saya memberi tahu Anda sekarang- setTimeout()bukan bagian dari JavaScript, meskipun console.log()atau peristiwa DOM semuanya adalah bagian dari API Web yang memberikan akses ke Mesin JavaScript untuk menggunakan semua propertinya dalam Konteks Eksekusi Global (GEC) melalui objek global window. API web ini disebut sebagai asynchronous .

Apa itu Antrean Panggilan Balik?

Antrean tugas yang disebut "antrian panggilan balik" atau "antrian tugas" adalah salah satu yang dijalankan setelah tugas tumpukan panggilan saat ini telah selesai. Tugas yang terdaftar di web API berpindah dari web API ke antrean callback.

Antrean panggilan balik berfungsi seperti struktur data antrean yang berarti bahwa tugas ditangani dalam urutan FIFO (masuk pertama, keluar pertama), berlawanan dengan tumpukan panggilan, yang berarti bahwa tugas ditangani sesuai urutan penambahannya ke antrean.

Antrean Panggilan Balik

Apa itu Putaran Acara?

Loop peristiwa JavaScript menambahkan tugas dari antrean panggilan balik ke tumpukan panggilan dalam urutan FIFO segera setelah tumpukan panggilan kosong.

Perulangan peristiwa diblokir jika tumpukan panggilan sedang menjalankan beberapa kode dan tidak akan menambahkan panggilan tambahan dari antrean sampai tumpukan kosong sekali lagi. Ini karena kode JavaScript dijalankan dengan cara run-to-completion.

Mari kita pahami konsep di atas dengan sebuah contoh.

  • Pada awalnya, Global Execution Contextdibuat untuk kode kita di dalam kita call stackdan GECmengeksekusi kode kita baris demi baris.
  • GECmengeksekusi baris pertama dan mencetak 'Mulai' di konsol kami.
  • Menjalankan baris ke-2, setTimeout()API web akan dipanggil dan kemudian setTimeout()memberikan akses fitur pengatur waktu. Kemudian Anda akan dapat mengatur 5000mssebagai waktu tunda.
  • Ketika Anda melewati callBack()fungsi melalui setTimeout(), itu callBack()akan didaftarkan sebagai Call Back over web Web API.
  • Dan kemudian GECmengeksekusi baris pertama serta mencetak 'Akhir' di konsol.
  • Ketika semua kode dieksekusi, GECakan dihapus dari call stack.
  • Setelah 5000 millisecond, callBack()fungsi yang terdaftar di web API, dipindahkan ke dalam call Back Queue.
  • Event loopmenempatkan callBack()fungsi ke dalam call Stackketika selesai semuanya berfungsi. Dan terakhir, callBack()fungsi dijalankan dan cetak 'Call Back' ke konsol.

function f1() {
    console.log('f1');
}

function f2() {
    console.log('f2');
}

function main() {
    console.log('main');
    
    setTimeout(f1, 0);
    
    f2();
}

main();

Jika Anda mengira “f1” akan dicetak sebelum “f2”, maka Anda salah. Itu akan terjadi -

main
f2
f1

Mekanisme JavaScript yang dibahas cocok untuk semua fungsi callback atau permintaan API.

Mari amati langkah demi langkah bagaimana contoh ke-2 bekerja di dalam lingkungan runtime.

  1. Mula-mula GECakan dibuat di dalam call stackdan kemudian kode akan dieksekusi baris demi baris di GEC. Ia menyimpan semua definisi fungsi di Memory Heap .
  2. Saat main()dipanggil, a Function Execution Context (FEC)dibuat dan kemudian masuk ke dalam tumpukan panggilan. Setelah itu semua kode main()fungsi akan dieksekusi baris demi baris.
  3. Ini memiliki log konsol untuk mencetak kata utama. Jadi console.log('main')eksekusi dan keluar dari tumpukan.
  4. setTimeout()API browser terjadi . Fungsi callback memasukkannya ke dalam antrian callback. Namun di stack, eksekusi terjadi seperti biasa, sehingga f2()masuk ke dalam stack. Log konsol f2()eksekusi. Keduanya keluar dari tumpukan.
  5. Dan kemudian main()juga muncul dari tumpukan.
  6. Perulangan peristiwa mengenali bahwa tumpukan panggilan kosong, dan ada fungsi panggilan balik dalam antrean. Jadi, fungsi callback f1()akan dimasukkan ke dalam stack oleh event loop. Eksekusi dimulai. Log konsol dijalankan, dan f1()juga keluar dari tumpukan. Dan akhirnya, tidak ada lagi yang ada di tumpukan dan antrean untuk dieksekusi lebih lanjut.

Ini latihan dan catatan saya. Jika menurut Anda ini bermanfaat, tunjukkan dukungan Anda dengan mengklik ikon tepuk tangan di bawah. Anda dapat mengikuti saya di media .