อธิบาย Node.js Event Loop
Node.js ใช้ Single Thread คุณอาจจะสงสัยว่ามันจัดการกับคำขอ (requests) นับพันพร้อมกันได้อย่างไร
เคล็ดลับก็คือ Event Loop
แทนที่จะรอให้งานหนึ่งเสร็จสิ้น Node.js จะส่งงานที่ต้องใช้เวลานานไปยังระบบปฏิบัติการ (OS) และข้ามไปทำงานถัดไปทันที สิ่งนี้ทำให้แอปพลิเคชันของคุณทำงานได้รวดเร็วและตอบสนองได้ดี
Blocking vs Non-blocking
หากคุณใช้ฟังก์ชันแบบ sync เช่น readFileSync เซิร์ฟเวอร์จะหยุดทำงานเพื่อรอให้การอ่านไฟล์เสร็จสิ้น ทำให้ผู้ใช้คนอื่นไม่ได้รับการตอบสนอง ซึ่งจะทำลายประสิทธิภาพของระบบคุณ
แต่ถ้าคุณใช้ fs.readFile เซิร์ฟเวอร์จะยังคงทำงานต่อไป โดยจะจัดการคำขออื่นๆ ในขณะที่การอ่านไฟล์กำลังดำเนินอยู่เบื้องหลัง
การทำงานของ Event Loop
Loop จะทำงานผ่านขั้นตอนต่างๆ ดังนี้:
• Timers: จัดการ setTimeout และ setInterval
• Pending Callbacks: จัดการข้อผิดพลาดในระดับระบบ (system level errors)
• Poll: รับการเชื่อมต่อใหม่และจัดการ I/O เช่น การคิวรีฐานข้อมูล (database queries)
• Check: จัดการ setImmediate
• Close Callbacks: จัดการการปิด socket
ลำดับความสำคัญ
งานทุกอย่างไม่ได้มีความสำคัญเท่ากัน Node.js ใช้คิว (queues) สองประเภท:
- Microtask Queue: ใช้เก็บ Promises
- Callback Queue: ใช้เก็บ
setTimeoutและ I/O
Microtask Queue จะทำงานก่อนเสมอ หากคุณมีทั้ง Promise และ setTimeout ตัว Promise จะทำงานเสร็จสิ้นก่อนตัวจับเวลา
Call Stack และ Queues
Call Stack จะติดตามว่าโค้ดส่วนไหนกำลังทำงานอยู่ในขณะนั้น เมื่อทำงานเสร็จสิ้น callback ของงานนั้นจะเข้าไปอยู่ในคิว และ Event Loop จะรอจนกว่า Call Stack จะว่างเปล่าก่อนที่จะดึงงานจากคิวมาทำงานต่อ
หลีกเลี่ยงข้อผิดพลาดเหล่านี้:
• อย่าใช้ infinite loops เพราะจะทำให้แอปพลิเคชันทั้งหมดค้าง • อย่าใช้ synchronous file methods ใน production • อย่ารันงานคำนวณหนักๆ หรือการประมวลผลวิดีโอบน main thread
สำหรับงานที่หนัก ให้ใช้ Worker Threads หรือ background jobs แทน
สรุป
Node.js ทำงานได้รวดเร็วเพราะมันไม่เสียเวลารอ มันจะส่งต่องาน I/O และใช้ Event Loop ในการจัดการผลลัพธ์ สถาปัตยกรรมนี้ช่วยให้ thread เดียวสามารถรองรับผู้ใช้งานจำนวนมากได้
ส่วนไหนของ Event Loop ที่คุณเรียนรู้ได้ยากที่สุด? บอกเราในคอมเมนต์ได้เลย