ข้ามไปยังเนื้อหา

Event Loop & Async

JavaScript ใน Node.js ทำงานบน เธรดเดียว (single thread) แต่กลับรองรับการเชื่อมต่อพร้อมกันได้นับพันโดยไม่บล็อก ความลับอยู่ที่ event loop — กลไกที่มอบงานช้า (อ่านไฟล์, เรียก network) ให้ระบบปฏิบัติการจัดการ แล้วค่อยประมวลผลผลลัพธ์เมื่อพร้อม

แก่นของ runtime มีโครงสร้างสำคัญสามอย่าง:

  • Call stack — ที่ที่โค้ดแบบ synchronous ทำงาน ทีละเฟรม
  • Microtask queue — เก็บ callback ของ Promise และ queueMicrotask ระบายจนหมดหลังจากทุก task
  • Macrotask queue (task queue) — เก็บ callback ของ setTimeout/setInterval ประมวลผลทีละหนึ่ง macrotask ต่อรอบ event loop

ลูปทำงานต่อเนื่อง: หยิบ macrotask → รัน → ระบาย microtask ทั้งหมด → หยิบ macrotask ถัดไป

บทเรียนหัวข้อ
Call Stackการทำงานแบบ synchronous และทำไมการบล็อกจึงสำคัญ
Callbacksรูปแบบ async ดั้งเดิมและขนบ error-first ของ Node
Promisesสถานะ, การ chain และ combinator
Async/Awaitอ่านโค้ด async ได้เหมือนโค้ด synchronous
Microtasks & Macrotasksลำดับความสำคัญของคิวและลำดับการระบาย
TimerssetTimeout, setInterval และความแม่นยำของ timer

สนิปเป็ตด้านล่างรันโค้ดสามชิ้น สังเกตว่าโค้ด ไม่ได้ ทำงานจากบนลงล่างตามลำดับที่เขียน — log แบบ synchronous ทำงานก่อน, callback ของ Promise ทำงานถัดมา (microtask), และ callback ของ setTimeout ทำงานเป็นอันสุดท้าย (macrotask)

// อะไรทำงานก่อน?
console.log('A — sync');
Promise.resolve().then(() => console.log('B — microtask (Promise)'));
setTimeout(() => console.log('C — macrotask (setTimeout)'), 0);

ลองรันเพื่อยืนยันลำดับ:

JavaScript

ผลลัพธ์จะเป็น A แล้วตามด้วย B แล้ว C เสมอ — event loop รับประกันลำดับนี้

หลังจากรัน task หนึ่ง event loop ประมวลผลคิวตามลำดับใด?
ข้อใดต่อไปนี้ถูกใส่ลงใน microtask queue?