ทำความเข้าใจ Event Loop ใน JavaScript อย่างลึกซึ้ง

Sharing is caring!

ภาพหน้าปก Event Loop JavaScript

บทนำ

ถ้าคุณเขียน JavaScript มาสักระยะแล้ว คงเคยสงสัยว่า JavaScript จัดการกับงานหลายอย่างพร้อมกันได้อย่างไร ทั้งที่เป็นภาษาแบบ single-threaded คำตอบของสิ่งนี้คือ Event Loop กลไกเบื้องหลังความสามารถ asynchronous ของ JavaScript ที่ทำให้เราสามารถใช้ setTimeout, fetch, Promise และ async/await ได้อย่างลื่นไหล

JavaScript เป็น Single-Threaded

JavaScript ดำเนินคำสั่งทีละบรรทัดใน Call Stack ซึ่งทำให้ดูเหมือนทำงานได้เพียงอย่างเดียวในแต่ละช่วงเวลา แต่เมื่อมีงานแบบ asynchronous เข้ามา JavaScript ต้องใช้ความช่วยเหลือจาก Web APIs และ Event Loop เพื่อจัดลำดับและควบคุมการทำงานให้ไม่บล็อกการประมวลผล

แผนผัง Event Loop แสดง Call Stack, Web APIs, Task Queue

องค์ประกอบหลักของ Event Loop

  • Call Stack: Stack สำหรับเรียกฟังก์ชันตามลำดับ
  • Web APIs: ฟีเจอร์ที่ browser มอบให้สำหรับงาน async เช่น setTimeout, fetch
  • Callback Queue (Task Queue): คิวที่เก็บ callback ที่รอเข้า Stack
  • Event Loop: กลไกที่ตรวจสอบ Stack และ Queue อย่างต่อเนื่อง

ตัวอย่างเบื้องต้น

console.log("1");
setTimeout(() => console.log("2"), 0);
console.log("3");

ผลลัพธ์:

1
3
2

แม้ว่า setTimeout ถูกตั้งเวลาเป็น 0 แต่ JavaScript จะรอจน Stack ว่างก่อนแล้วจึงนำ callback เข้าคิว

Microtask Queue คืออะไร?

JavaScript มีอีกคิวหนึ่งชื่อว่า Microtask Queue ซึ่งใช้สำหรับ Promise และ async/await โดยจะมีลำดับความสำคัญสูงกว่า Task Queue

console.log("A");

Promise.resolve().then(() => console.log("B"));

setTimeout(() => console.log("C"), 0);

console.log("D");

ผลลัพธ์คือ:

A
D
B
C

การทำงานของ async/await

async/await เป็น syntax ที่ใช้จัดการ promise ได้อย่างสะอาดเข้าใจง่าย แต่เบื้องหลังยังคงใช้ microtask queue

async function run() {
  console.log("1");
  await Promise.resolve();
  console.log("2");
}
run();
console.log("3");

ผลลัพธ์:

1
3
2

คำสั่งหลัง await จะถูก queue ไปไว้ใน microtask queue

แผนภาพลำดับงาน

  1. Stack ทำงาน synchronous ปกติ
  2. เมื่อมี async function → ถูกส่งไปยัง Web APIs
  3. เมื่อเสร็จ → callback ถูกส่งไป Task หรือ Microtask Queue
  4. Event Loop ตรวจสอบ ถ้า Stack ว่าง → ดึง callback เข้า Stack

ข้อควรระวัง

  • ไม่ควรมี loop ใหญ่ที่บล็อก stack เพราะจะทำให้ callback ค้าง
  • microtask queue ไม่มีการจำกัดจำนวน ถ้าสร้าง promise แบบวนลูปอาจทำให้ browser ค้าง
  • ระวัง callback hell ควรใช้ async/await หรือ compose function

สรุป

Event Loop เป็นกลไกที่ทำให้ JavaScript รองรับ asynchronous ได้อย่างมีประสิทธิภาพ การเข้าใจการทำงานของมันจะช่วยให้คุณเขียนโค้ดที่เข้าใจง่าย แก้บั๊กได้เร็ว และออกแบบระบบที่ responsive ต่อผู้ใช้

ใช้เวลาอ่าน: 10 – 15 นาที | เขียนโดย: ทีมงาน poolsawat.com

Leave a Reply

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *