ทำความเข้าใจ Node.js Event Loop

Event Loop ไม่ใช่คนทำงาน แต่มันคือผู้ประสานงาน

นักพัฒนาหลายคนพบว่า Event Loop นั้นมีความซับซ้อน ความยากมักเกิดจากการนำแนวคิดหลายอย่างมาปนกันในคราวเดียว คุณต้องติดตามทั้ง libuv, Call Stack, Promises และ I/O ไปพร้อมๆ กัน

นี่คือความจริงที่เรียบง่าย: Event Loop ทำหน้าที่จัดตารางงาน แต่มันไม่ได้เป็นคนทำงานนั้นเอง

JavaScript ทำงานบน single thread ซึ่งหมายความว่าโค้ดจะทำงานเป็นเส้นตรง งานหนึ่งต้องเสร็จสิ้นก่อนที่งานถัดไปจะเริ่มขึ้น เราจึงต้องการระบบเพื่อจัดการงานแบบ asynchronous เช่น การอ่านไฟล์หรือการร้องขอผ่านเครือข่าย โดยไม่ทำให้โปรแกรมทั้งหมดต้องหยุดชะงัก

หลักการทำงาน:

Event Loop จะย้าย callback จากคิวต่างๆ เข้าสู่ Call Stack ให้ลองนึกภาพว่าแต่ละ phase คือแถวคอย และ Event Loop คือคนที่คอยพาคนจากแถวเข้าไปในห้อง

Phase หลักๆ มีดังนี้:

ข้อผิดพลาดที่พบบ่อยคือการคิดว่า Event Loop มี Call Stack เป็นของตัวเอง ซึ่งจริงๆ แล้วไม่ใช่ Runtime มี Call Stack เพียงอันเดียวและมี microtask queue เพียงอันเดียว

กระบวนการทำงานมีลำดับดังนี้:

  1. Event Loop เลือก callback จาก phase ปัจจุบัน
  2. มันจะ push callback นั้นเข้าไปใน Call Stack
  3. Call Stack จะรันโค้ดนั้น
  4. เมื่อ callback ทำงานเสร็จสิ้น engine จะเคลียร์ microtask queue ซึ่งเป็นที่ที่ Promises และ async/await ทำงานอยู่
  5. Event Loop จะย้ายไปยัง phase ถัดไป

หากคุณใช้ setTimeout(..., 0) มันจะไปที่ phase Timers หากคุณใช้ setImmediate(...) มันจะไปที่ phase Check

งานหนักๆ จะเกิดขึ้นใน OS kernel และ libuv ส่วน Event Loop มีหน้าที่เพียงแค่บอก JavaScript ว่าถึงเวลาที่ต้องตอบสนองแล้ว

แหล่งที่มา: https://dev.to/joaovictor6/event-loop-entendendo-uma-das-bases-do-node-41a