Rumah > Artikel > hujung hadapan web > Memahami Pengaturcaraan Asynchronous dalam JavaScript: Panduan Pemula untuk Gelung Acara
Pernahkah anda terfikir mengapa beberapa keping kod JavaScript kelihatan kehabisan pesanan? Kunci untuk memahami perkara ini ialah gelung acara.
Gelung acara JavaScript boleh menjadi sukar untuk difahami, terutamanya apabila berurusan dengan pelbagai jenis operasi tak segerak. Dalam artikel ini, kami akan membahagikan cara JavaScript mengendalikan kod segerak dan tak segerak, tugas mikro dan tugasan makro serta sebab perkara tertentu berlaku dalam susunan tertentu.
JavaScript mengendalikan operasi dalam dua cara utama: synchronous dan asynchronous. Memahami perbezaan antara mereka adalah kunci untuk memahami cara JavaScript mengendalikan tugas dan cara menulis kod yang cekap dan tidak menyekat.
Kod segerak ialah lalai dalam JavaScript, bermakna setiap baris berjalan satu demi satu dalam urutan. Contohnya:
console.log("First"); console.log("Second");
Ini akan menghasilkan:
First Second
Kod tak segerak sebaliknya membenarkan tugasan tertentu dijalankan di latar belakang dan diselesaikan kemudian, tanpa menyekat kod yang lain. Fungsi seperti setTimeout() atau Promise ialah contoh kod tak segerak.
Berikut ialah contoh mudah kod tak segerak menggunakan setTimeout():
console.log("First"); setTimeout(() => { console.log("Second"); }, 0); console.log("Third");
Ini akan menghasilkan:
First Third Second
Terdapat beberapa cara untuk mengendalikan operasi tak segerak dalam JavaScript:
Contoh Kod:
console.log("Start"); function asyncTask(callback) { setTimeout(() => { console.log("Async task completed"); callback(); }, 2000); } asyncTask(() => { console.log("Task finished"); }); console.log("End");
Contoh Kod:
console.log("Start"); const asyncTask = new Promise((resolve) => { setTimeout(() => { console.log("Async task completed"); resolve(); }, 2000); }); asyncTask.then(() => { console.log("Task finished"); }); console.log("End");
Contoh Kod:
console.log("Start"); async function asyncTask() { await new Promise((resolve) => { setTimeout(() => { console.log("Async task completed"); resolve(); }, 2000); }); console.log("Task finished"); } asyncTask(); console.log("End");
Untuk lebih memahami setiap kaedah pelaksanaan javascript ini dan bagaimana ia berbeza daripada setiap satu sama ada, berikut ialah perbezaan terperinci merentas pelbagai aspek fungsi javascript.
Aspect | Synchronous Code | Asynchronous Code |
---|---|---|
Execution Order | Executes line by line in a sequential manner | Allows tasks to run in the background while other code continues to execute |
Performance | Can lead to performance issues if long-running tasks are involved | Better performance for I/O-bound operations; prevents UI freezing in browser environments |
Code Complexity | Generally simpler and easier to read | Can be more complex, especially with nested callbacks (callback hell) |
Memory Usage | May use more memory if waiting for long operations | Generally more memory-efficient for long-running tasks |
Scalability | Less scalable for applications with many concurrent operations | More scalable, especially for applications handling multiple simultaneous operations |
This comparison highlights the key differences between synchronous and asynchronous code, helping developers choose the appropriate approach based on their specific use case and performance requirements.
In JavaScript, microtasks and macrotasks are two types of tasks that are queued and executed in different parts of the event loop, which determines how JavaScript handles asynchronous operations.
Microtasks and macrotasks are both queued and executed in the event loop, but they have different priorities and execution contexts. Microtasks are processed continuously until the microtask queue is empty before moving on to the next task in the macrotask queue. Macrotasks, on the other hand, are executed after the microtask queue has been emptied and before the next event loop cycle starts.
Microtasks are tasks that need to be executed after the current operation completes but before the next event loop cycle starts. Microtasks get priority over macrotasks and are processed continuously until the microtask queue is empty before moving on to the next task in the macrotask queue.
console.log("Start"); Promise.resolve().then(() => { console.log("Microtask"); }); console.log("End");
Start End Microtask
Macrotasks are tasks that are executed after the microtask queue has been emptied and before the next event loop cycle starts. These tasks represent operations like I/O or rendering and are usually scheduled after a certain event or after a delay.
console.log("Start"); setTimeout(() => { console.log("Macrotask"); }, 0); console.log("End");
Start End Macrotask
Aspect | Microtasks | Macrotasks |
---|---|---|
Execution Timing | Executed immediately after the current script, before rendering | Executed in the next event loop iteration |
Queue Priority | Higher priority, processed before macrotasks | Lower priority, processed after all microtasks are complete |
Examples | Promises, queueMicrotask(), MutationObserver | setTimeout(), setInterval(), I/O operations, UI rendering |
Use Case | For tasks that need to be executed as soon as possible without yielding to the event loop | For tasks that can be deferred or don't require immediate execution |
Gelung peristiwa ialah konsep asas dalam JavaScript yang membolehkan operasi tak segerak tanpa sekatan walaupun JavaScript berbenang tunggal. Ia bertanggungjawab untuk mengendalikan panggilan balik tak segerak dan memastikan JavaScript terus berjalan lancar tanpa disekat oleh operasi yang memakan masa.
Gelung acara ialah mekanisme yang membenarkan JavaScript mengendalikan operasi tak segerak dengan cekap. Ia sentiasa menyemak timbunan panggilan dan baris gilir tugas (atau baris gilir microtask) untuk menentukan fungsi mana yang perlu dilaksanakan seterusnya.
Untuk memahami gelung acara dengan lebih baik, adalah penting untuk mengetahui cara JavaScript berfungsi secara dalaman. Adalah penting untuk ambil perhatian bahawa JavaScript ialah bahasa benang tunggal, bermakna ia hanya boleh melakukan satu perkara pada satu masa. Terdapat hanya satu timbunan panggilan, yang menyimpan fungsi yang akan dilaksanakan. Ini menjadikan kod segerak mudah, tetapi ia menimbulkan masalah untuk tugas seperti mengambil data daripada pelayan atau menetapkan tamat masa, yang mengambil masa untuk diselesaikan. Tanpa gelung acara, JavaScript akan tersekat menunggu tugasan ini dan tiada perkara lain yang akan berlaku.
Timbunan panggilan ialah tempat fungsi yang sedang dilaksanakan disimpan. JavaScript menambah dan mengalih keluar fungsi daripada tindanan panggilan semasa ia memproses kod.
Apabila tugas tak segerak seperti setTimeout, fetch atau Promise ditemui, JavaScript mewakilkan tugas itu kepada API Web penyemak imbas (seperti API Pemasa, API Rangkaian, dll.), yang mengendalikan tugas di latar belakang.
Setelah tugas tak segerak selesai (cth., pemasa selesai, atau data diterima daripada pelayan), panggilan balik (fungsi untuk mengendalikan hasil) dialihkan ke baris gilir tugas (atau baris gilir microtask dalam kes janji) .
JavaScript terus melaksanakan kod segerak. Setelah tindanan panggilan kosong, gelung acara mengambil tugasan pertama daripada baris gilir tugas (atau baris gilir microtask) dan meletakkannya pada tindanan panggilan untuk pelaksanaan.
Proses ini berulang. Gelung peristiwa memastikan semua tugas tak segerak dikendalikan selepas tugas segerak semasa selesai.
Sekarang kita memahami dengan lebih baik dan lebih jelas tentang cara gelung acara berfungsi, mari lihat beberapa contoh untuk mengukuhkan pemahaman kita.
function exampleOne() { console.log("Start"); setTimeout(() => { console.log("Timeout done"); }, 1000); Promise.resolve().then(() => { console.log("Resolved"); }); console.log("End"); } exampleOne();
Start End Resolved Timeout done
function exampleTwo() { console.log("Start"); setTimeout(() => { console.log("Timer 1"); }, 0); Promise.resolve().then(() => { console.log("Promise 1 Resolved"); setTimeout(() => { console.log("Timer 2"); }, 0); return Promise.resolve().then(() => { console.log("Promise 2 Resolved"); }); }); console.log("End"); } exampleTwo();
Start End Promise 1 Resolved Promise 2 Resolved Timer 1 Timer 2
function exampleThree() { console.log("Step 1: Synchronous"); setTimeout(() => { console.log("Step 2: Timeout 1"); }, 0); Promise.resolve().then(() => { console.log("Step 3: Promise 1 Resolved"); Promise.resolve().then(() => { console.log("Step 4: Promise 2 Resolved"); }); setTimeout(() => { console.log("Step 5: Timeout 2"); }, 0); }); setTimeout(() => { console.log( "Step 6: Immediate (using setTimeout with 0 delay as fallback)" ); }, 0); console.log("Step 7: Synchronous End"); } exampleThree();
Step 1: Synchronous Step 7: Synchronous End Step 3: Promise 1 Resolved Step 4: Promise 2 Resolved Step 2: Timeout 1 Step 6: Immediate (using setTimeout with 0 delay as fallback) Step 5: Timeout 2
In JavaScript, mastering synchronous and asynchronous operations, as well as understanding the event loop and how it handles tasks, is crucial for writing efficient and performant applications.
The examples provided progressively illustrated the interaction between synchronous code, promises, timers, and the event loop. Understanding these concepts is key to mastering asynchronous programming in JavaScript, ensuring your code runs efficiently and avoids common pitfalls such as race conditions or unexpected execution orders.
To ensure you don't miss any part of this series and to connect with me for more in-depth discussions on Software Development (Web, Server, Mobile or Scraping / Automation), push notifications, and other exciting tech topics, follow me on:
Stay tuned and happy coding ???
Atas ialah kandungan terperinci Memahami Pengaturcaraan Asynchronous dalam JavaScript: Panduan Pemula untuk Gelung Acara. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!