Model eksekusi JavaScript bernuansa dan mudah disalahpahami. Mempelajari tentang loop acara pada intinya dapat membantu.
JavaScript adalah bahasa utas tunggal, dibuat untuk menangani tugas satu per satu. Namun, loop peristiwa memungkinkan JavaScript menangani peristiwa dan panggilan balik secara asinkron dengan meniru sistem pemrograman simultan. Ini menjamin kinerja aplikasi JavaScript Anda.
Apa itu Loop Acara JavaScript?
Loop acara JavaScript adalah mekanisme yang berjalan di latar belakang setiap aplikasi JavaScript. Ini memungkinkan JavaScript menangani tugas secara berurutan tanpa memblokir utas eksekusi utamanya. Ini disebut sebagai pemrograman asinkron.
Perulangan peristiwa menyimpan antrean tugas untuk dijalankan dan mengumpankan tugas tersebut ke kanan API web untuk eksekusi satu per satu. JavaScript melacak tugas-tugas ini dan menangani masing-masing sesuai dengan tingkat kerumitan tugas.
Untuk memahami kebutuhan loop peristiwa JavaScript dan pemrograman asinkron. Anda perlu memahami masalah apa yang pada dasarnya dipecahkannya.
Ambil kode ini, misalnya:
functionlongRunningFunction() {
// This function does something that takes a long time to execute.
for (var i = 0; i < 100000; i++) {
console.log("Hello")
}
}functionshortRunningFunction(a) {
return a * 2 ;
}functionmain() {
var startTime = Date.now();
longRunningFunction();
var endTime = Date.now();// Prints the amount of time it took to execute functions
console.log(shortRunningFunction(2));
console.log("Time taken: " + (endTime - startTime) + " milliseconds");
}
main();
Kode ini pertama-tama mendefinisikan fungsi yang dipanggil longRunningFunction(). Fungsi ini akan melakukan semacam tugas yang memakan waktu yang rumit. Dalam hal ini, ia melakukan a untuk loop iterasi lebih dari 100.000 kali. Ini berarti bahwa console.log("Halo") berjalan 100.000 kali lipat.
Bergantung pada kecepatan komputer, ini bisa memakan waktu lama dan memblokir shortRunningFunction() dari eksekusi langsung hingga fungsi sebelumnya selesai.
Untuk konteksnya, berikut adalah perbandingan waktu yang dibutuhkan untuk menjalankan kedua fungsi tersebut:
Dan kemudian single shortRunningFunction():
Perbedaan antara operasi 2.351 milidetik dan operasi 0 milidetik terlihat jelas saat Anda ingin membuat aplikasi yang berkinerja baik.
Bagaimana Event Loop Membantu Performa Aplikasi
Loop acara memiliki tahapan dan bagian berbeda yang berkontribusi untuk membuat sistem berfungsi.
Tumpukan Panggilan
Tumpukan panggilan JavaScript sangat penting untuk bagaimana JavaScript menangani panggilan fungsi dan peristiwa dari aplikasi Anda. Kode JavaScript dikompilasi dari atas ke bawah. Namun, Node.js, saat membaca kode, Node.js akan menetapkan pemanggilan fungsi dari bawah ke atas. Saat membaca, itu mendorong fungsi yang ditentukan sebagai bingkai ke dalam tumpukan panggilan satu per satu.
Tumpukan panggilan bertanggung jawab untuk menjaga konteks eksekusi dan urutan fungsi yang benar. Ini dilakukan dengan beroperasi sebagai tumpukan Last-In-First-Out (LIFO).
Ini berarti bahwa bingkai fungsi terakhir yang didorong oleh program Anda ke tumpukan panggilan akan menjadi yang pertama keluar dari tumpukan dan dijalankan. Ini akan memastikan JavaScript mempertahankan urutan eksekusi fungsi yang benar.
JavaScript akan mengeluarkan setiap frame dari tumpukan hingga kosong, artinya semua fungsi telah selesai dijalankan.
API Web Libuv
Inti dari program asinkron JavaScript adalah libuv. Pustaka libuv ditulis dalam bahasa pemrograman C, yang dapat berinteraksi dengan sistem operasi API tingkat rendah. Pustaka akan menyediakan beberapa API yang memungkinkan kode JavaScript berjalan paralel dengan lainnya kode. API untuk membuat utas, API untuk komunikasi antar utas, dan API untuk mengelola sinkronisasi utas.
Misalnya, saat Anda menggunakan setTimeout di Node.js untuk menjeda eksekusi. Pengatur waktu diatur melalui libuv, yang mengelola perulangan peristiwa untuk menjalankan fungsi panggilan balik setelah penundaan yang ditentukan berlalu.
Demikian pula, ketika Anda melakukan operasi jaringan secara asinkron, libuv menangani operasi tersebut secara non-pemblokiran cara, memastikan bahwa tugas lain dapat melanjutkan pemrosesan tanpa menunggu operasi input/output (I/O). akhir.
Panggilan Balik & Antrean Acara
Antrean callback & event adalah tempat fungsi callback menunggu eksekusi. Saat operasi asinkron selesai dari libuv, fungsi callback yang sesuai akan ditambahkan ke antrean ini.
Begini urutannya:
- JavaScript memindahkan tugas asinkron ke libuv untuk ditangani, dan terus menangani tugas berikutnya dengan segera.
- Saat tugas asinkron selesai, JavaScript menambahkan fungsi panggilan baliknya ke antrean panggilan balik.
- JavaScript terus menjalankan tugas lain di tumpukan panggilan hingga selesai dengan semua yang ada dalam urutan saat ini.
- Setelah tumpukan panggilan kosong, JavaScript melihat antrian panggilan balik.
- Jika ada panggilan balik dalam antrean, panggilan pertama akan didorong ke tumpukan panggilan dan dijalankan.
Dengan cara ini, tugas asinkron tidak memblokir utas utama, dan antrean callback memastikan bahwa callback terkait dijalankan sesuai urutan penyelesaiannya.
Siklus Lingkaran Peristiwa
Loop acara juga memiliki sesuatu yang disebut antrean microtask. Antrean khusus dalam loop peristiwa ini menyimpan tugas-tugas mikro yang dijadwalkan untuk dieksekusi segera setelah tugas saat ini dalam tumpukan panggilan selesai. Eksekusi ini terjadi sebelum perenderan berikutnya atau iterasi loop peristiwa. Microtasks adalah tugas berprioritas tinggi dengan prioritas di atas tugas reguler dalam loop acara.
Microtask biasanya dibuat saat bekerja dengan Promises. Setiap kali Janji menyelesaikan atau menolak, itu sesuai .Kemudian() atau .menangkap() callback bergabung dengan antrian microtask. Anda dapat menggunakan antrean tersebut untuk mengelola tugas yang memerlukan eksekusi segera setelah operasi saat ini, seperti memperbarui UI aplikasi Anda atau menangani perubahan status.
Misalnya, aplikasi web yang melakukan pengambilan data dan memperbarui UI berdasarkan data yang diambil. Pengguna dapat memicu pengambilan data ini dengan mengklik tombol berulang kali. Setiap klik tombol memulai operasi pengambilan data asinkron.
Tanpa microtasks, loop acara untuk tugas ini akan berfungsi sebagai berikut:
- Pengguna mengklik tombol berulang kali.
- Setiap klik tombol memicu operasi pengambilan data asinkron.
- Saat operasi pengambilan data selesai, JavaScript menambahkan callback yang sesuai ke antrean tugas biasa.
- Putaran peristiwa mulai memproses tugas dalam antrean tugas biasa.
- Pembaruan UI berdasarkan hasil pengambilan data dijalankan segera setelah tugas reguler mengizinkannya.
Namun, dengan microtasks, loop acara bekerja secara berbeda:
- Pengguna mengklik tombol berulang kali dan memicu operasi pengambilan data asinkron.
- Saat operasi pengambilan data selesai, loop peristiwa menambahkan callback yang sesuai ke antrean microtask.
- Loop peristiwa mulai memproses tugas dalam antrean tugas mikro segera setelah menyelesaikan tugas saat ini (klik tombol).
- Pembaruan UI berdasarkan hasil pengambilan data dijalankan sebelum tugas reguler berikutnya, memberikan pengalaman pengguna yang lebih responsif.
Berikut ini contoh kode:
const fetchData = () => {
returnnewPromise(resolve => {
setTimeout(() => resolve('Data from fetch'), 2000);
});
};
document.getElementById('fetch-button').addEventListener('click', () => {
fetchData().then(data => {
// This UI update will run before the next rendering cycle
updateUI(data);
});
});
Dalam contoh ini, setiap klik pada tombol "Ambil" memanggil ambilData(). Setiap jadwal operasi pengambilan data sebagai microtask. Berdasarkan data yang diambil, update UI dijalankan segera setelah setiap operasi pengambilan selesai, sebelum tugas perenderan atau loop peristiwa lainnya.
Ini memastikan bahwa pengguna melihat data yang diperbarui tanpa mengalami penundaan karena tugas lain di loop acara.
Menggunakan microtasks dalam skenario seperti ini dapat mencegah UI jank dan menyediakan interaksi yang lebih cepat dan lancar di aplikasi Anda.
Implikasi dari Event Loop untuk Pengembangan Web
Memahami loop peristiwa dan cara menggunakan fitur-fiturnya sangat penting untuk membangun aplikasi yang berkinerja dan responsif. Event loop menyediakan kemampuan asinkron dan paralel, sehingga Anda dapat menangani tugas kompleks secara efisien di aplikasi Anda tanpa mengorbankan pengalaman pengguna.
Node.js menyediakan semua yang Anda butuhkan, termasuk pekerja web untuk mencapai paralelisme lebih jauh di luar utas utama JavaScript.