Back to notes
foundations-cs
Featured

JavaScript Event Loop Mastery: เชฟมือหนึ่งกับระบบคิวอัจฉริยะ

เจาะลึกกลไกการทำงานของ Event Loop ตั้งแต่ปัญหา Thread ค้าง ไปจนถึงความต่างระหว่าง Macrotask และ Microtask พร้อมตารางเปรียบเทียบเชิงลึก

January 30, 20262 min read readNNexis by Seereen

🛑 1. The Problem First: วันที่ "เชฟ" ตัวแข็งทื่อ

ใน JavaScript ทุกอย่างทำงานบน Single Thread (ทำงานทีละอย่าง)

ลองดูโค้ดที่ "ขวางโลก" บรรทัดนี้:

HLJS JAVASCRIPT
// ❌ Naive Approach: ทำงานหนักขวาง Main Thread
console.log("เริ่มงาน");
while (true) {
  /* ทำอะไรบางอย่างที่ไม่มีวันจบ */
}
console.log("จบงาน"); // บรรทัดนี้จะไม่มีวันถูกประหาร!

ปัญหา: เมื่อคุณทำอะไรที่หนักเกินไปบน Main Thread (เช่น Loop ข้อมูลหมื่นล้านตัว) Browser จะ "ค้าง" ทันที ลูกค้าคลิกปุ่มไม่ได้ ขยับเมาส์ไม่ไป เว็บคุณจะกลายเป็น "เว็บผีดิบ" นี่คือเหตุผลที่เราต้องการ Asynchronous ครับ


💡 2. Real-Life Analogy: เชฟมือไวกับเตาอบวิเศษ

ลองนึกภาพว่าคุณเป็น "เชฟที่ทำอาหารคนเดียว (Single Thread)".

  • Call Stack: คือเขียงหน้าตัวคุณ คุณหั่นผักได้ทีละอย่าง (Push/Pop Stack)
  • Web API (Oven): คือเตาอบวิเศษ คุณมีผู้ช่วยยืนคุมเตาให้ คุณแค่เอาไก่ใส่เตาแล้วบอกว่า "สุกเมื่อไหร่บอกด้วยนะ" (setTimeout/Fetch) จากนั้นคุณก็กลับไปหั่นผักอย่างอื่นต่อ ไม่ต้องยืนจ้องเตา
  • Task Queue (Waiter): คือบริกรที่ถือถาดอาหารที่สุกแล้วมายืนรอ เมื่อไหร่ที่คุณหั่นผักเสร็จและเขียงว่าง (Stack Empty) บริกรจะเอาไก่จากเตามาวางบนเขียงให้คุณจัดจานต่อ (Event Loop)

🚀 3. Execution Journey: เส้นทางเดินของบัตรคิว

เมื่อคุณรันโค้ด Async นี่คือลำดับเหตุการณ์จริง:

🛠 Step-by-step:

  1. Executing: โค้ดส่วนที่รันได้เลยจะไปอยู่ที่ Call Stack
  2. Offloading: โค้ดที่เป็น Async (setTimeout, API) จะถูกโยนไปให้ Browser ทำแทน
  3. Queueing: เมื่อเสร็จแล้ว Browser จะส่ง Callback ไปรอที่ Queue
  4. Looping: Event Loop จะ "ชะโงกหน้า" ดู Call Stack ตลอดเวลา ถ้าว่างเป๊ะ! มันจะดึงงานจาก Queue ขึ้นมาทำทันที
HLJS JAVASCRIPT
// ✅ Best Practice: เข้าใจลำดับความสำคัญ
console.log("1. ปกติ");

setTimeout(() => console.log("4. แถวธรรมดา"), 0); // Macrotask

Promise.resolve().then(() => console.log("3. VIP")); // Microtask

console.log("2. ปกติ");

ผลลัพธ์: 1 -> 2 -> 3 -> 4 (VIP แซงคิวเสมอ!)


🪤 4. The Junior Trap: โรค "await หยุดโลก"

จูเนียร์มักจะเข้าใจว่า await คือการหยุดทุกอย่าง:

HLJS JAVASCRIPT
async function getData() {
  const res = await fetch("/api/data"); // ❌ คิดว่า JS จะหยุดรอตรงนี้ไปเลย
  console.log(res);
}

ระวัง: await ไม่ได้หยุด Main Thread! มันแค่ "พักงาน" ฟังก์ชันนี้ไว้ แล้ว Event Loop จะไปทำงานอื่นต่อ เมื่อข้อมูลมาถึงค่อยกลับมาทำบรรทัดถัดไป ถ้าคุณใช้ await ใน Loop เยอะๆ โดยไม่จำเป็น โปรแกรมคุณจะช้าลงมหาศาล ✅ การแก้ไข: ใช้ Promise.all() เพื่อยิงงานหลายๆ อย่างไปพร้อมกัน


⚖️ 5. The Why Matrix: Microtask vs Macrotask

ประเภทตัวอย่างลำดับความสำคัญ
Call Stackโค้ดปกติ, ฟังก์ชันทั่วไปสูงสุด (ทำทันที)
Microtask (VIP)Promise.then, awaitรองลงมา (ต้องเคลียร์ให้หมดก่อนไปแถวอื่น)
MacrotasksetTimeout, setIntervalต่ำสุด (ทำทีละอย่างหลังจากเคลียร์ VIP หมด)

🎓 6. Senior Mindset Summary

การเป็น Senior คือการรู้ว่า "Main Thread คือสมบัติอันมีค่าที่สุด" อย่าทำงานที่หนักเกินไปบนนั้น และต้องเข้าใจลำดับคิวให้แม่นยำเพื่อป้องกันบั๊กประเภท "ทำไมข้อมูลยังไม่มาแต่โค้ดรันไปแล้ว" ครับ!

Share this note

© 2026 My Notes by Seereen