[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"academy-blogs-th-1-1-all-javascript-event-loop-runtime-explained-all--*":3,"academy-blog-translations-m8p00ws3k9oym5h":90},{"data":4,"page":89,"perPage":89,"totalItems":89,"totalPages":89},[5],{"alt":6,"collectionId":7,"collectionName":8,"content":9,"cover_image":10,"cover_image_path":11,"created":12,"created_by":13,"expand":14,"id":83,"keywords":84,"locale":56,"published_at":85,"scheduled_at":13,"school_blog":79,"short_description":86,"status":77,"title":87,"updated":88,"updated_by":13,"slug":80,"views":82},"ไดอะแกรมแสดงการทำงานของ JavaScript Event Loop เชื่อมโยงระหว่าง Call Stack, Web APIs และ Task Queue","sclblg987654321","school_blog_translations","\u003Cp>เคยสงสัยไหมครับว่า ทำไม JavaScript ที่ทำงานแบบ \u003Cstrong>Single-threaded\u003C\u002Fstrong> (จัดการได้ทีละงาน) ถึงสามารถรับส่งข้อมูลจาก API, ประมวลผลการพิมพ์คีย์บอร์ด และรัน Animation ลื่นๆ บนหน้าจอไปพร้อมกันได้โดยไม่เกิดอาการหน้าจอค้าง?\u003C\u002Fp>\u003Cp>ความลับนี้ไม่ได้ซ่อนอยู่ในไวยากรณ์ของภาษาครับ แต่มันคือการทำงานร่วมกันอย่างเป็นระบบระหว่าง \u003Cstrong>JavaScript Engine\u003C\u002Fstrong> (อย่าง V8) และกลไกที่เรียกว่า \u003Cstrong>Event Loop\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>วันนี้เราจะมาแกะรอยการทำงานแบบ \u003Cstrong>Non-blocking I\u002FO\u003C\u002Fstrong> ที่ทำให้ JavaScript กลายเป็นภาษาที่ทรงพลังที่สุดตัวหนึ่งในโลกของการพัฒนาเว็บกันครับ!\u003C\u002Fp>\u003Cdiv data-type=\"html-block\" data-html=\"&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https:\u002F\u002Fwww.youtube.com\u002Fembed\u002FF7tm_rcfBhs?si=vnvclLx1rNG-Hq-f&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;\u002Fiframe&gt;\">\u003C\u002Fdiv>\u003Ch2>Event Loop คืออะไร?\u003C\u002Fh2>\u003Cp>ถ้าจะนิยามให้สั้นที่สุด \u003Cstrong>Event Loop คือ กลไกการจัดการลำดับการทำงาน (Orchestrator) ของ JavaScript\u003C\u002Fstrong> ครับ\u003C\u002Fp>\u003Cp>แม้ว่าตัวภาษา JavaScript จะทำงานแบบ \u003Cstrong>Single-threaded\u003C\u002Fstrong> คือมีทางเดินเดียวและทำได้ทีละอย่าง (เหมือนถนนเลนเดียว) แต่ Event Loop คือสิ่งที่เข้ามาช่วยบริหารจัดการว่างานไหนควรทำทันที และงานไหนควรส่งไปรอทำทีหลัง เพื่อให้โปรแกรมสามารถทำงานหลายอย่างพร้อมกันได้ (Asynchronous) โดยไม่เกิดอาการค้างหรือรอคำสั่งนานเกินไป\u003C\u002Fp>\u003Cp>หน้าที่หลักของมันมีเพียงอย่างเดียวคือ: \u003Cstrong>การเฝ้าดู (Monitoring)\u003C\u002Fstrong> มันจะคอยส่องดูว่าถ้า Call Stack ว่างลงเมื่อไหร่ มันจะไปหยิบงานที่รออยู่ใน Task Queue ขึ้นมาทำต่อทันที กระบวนการนี้จะวนซ้ำไปเรื่อยๆ เป็นวงกลม จึงเป็นที่มาของชื่อคำว่า \u003Cstrong>Loop\u003C\u002Fstrong> นั่นเองครับ\u003C\u002Fp>\u003Ch2>เจาะลึก 4 ส่วนประกอบหลักที่ทำให้ JavaScript ทำงานได้\u003C\u002Fh2>\u003Cp>การจะเข้าใจ Event Loop เราต้องเห็นภาพรวมก่อนว่า JavaScript Runtime (ไม่ว่าจะเป็น V8 ใน Chrome หรือ Node.js) แบ่งหน้าที่การจัดการ Code ออกเป็นส่วนๆ ดังนี้ครับ:\u003C\u002Fp>\u003Ch3>1. Call Stack\u003C\u002Fh3>\u003Cp>ส่วนนี้คือที่ที่ JavaScript รันคำสั่งต่างๆ ตามลำดับ (Single Thread) โดยทำงานแบบ \u003Cstrong>LIFO (Last In, First Out)\u003C\u002Fstrong> เมื่อมีการเรียก Function ระบบจะดัน (Push) เข้าไปใน Stack และเมื่อทำงานเสร็จถึงจะดึง (Pop) ออกมา\u003C\u002Fp>\u003Ch3>2. Web APIs \u002F Node.js APIs\u003C\u002Fh3>\u003Cp>นี่คือส่วนที่ช่วยให้ JavaScript ทำงานแบบ \u003Cstrong>Asynchronous\u003C\u002Fstrong> ได้จริง เพราะคำสั่งประเภทที่ต้องรอ เช่น \u003Ccode>setTimeout\u003C\u002Fcode>, \u003Ccode>fetch\u003C\u002Fcode> (Network Request) หรือการดักจับ Event ต่างๆ จะถูกส่งมาจัดการที่นี่แทน เพื่อไม่ให้ไปขวางการรัน Code ส่วนอื่นใน Call Stack\u003C\u002Fp>\u003Ch3>3. Task Queue (Callback Queue)\u003C\u002Fh3>\u003Cp>เมื่อคำสั่งในส่วน Web APIs ทำงานเสร็จสิ้น (เช่น ดึงข้อมูลเสร็จ หรือครบเวลาที่ตั้งไว้) ตัว Callback Function จะถูกส่งมาต่อคิวที่นี่เพื่อรอจังหวะกลับเข้าไปรันต่อ\u003C\u002Fp>\u003Ch3>4. Event Loop\u003C\u002Fh3>\u003Cp>ส่วนนี้ทำหน้าที่เป็นตัวประสานงานเพียงอย่างเดียวครับ คือคอยตรวจสอบสถานะของ Call Stack ถ้า Stack ว่างเมื่อไหร่ มันจะดึงคิวงานจาก Task Queue ขึ้นไปประมวลผลทันที กระบวนการนี้เกิดขึ้นซ้ำๆ ตลอดเวลาที่โปรแกรมทำงาน\u003C\u002Fp>\u003Ch2>ลำดับการทำงาน (Execution Flow) ทีละขั้นตอน\u003C\u002Fh2>\u003Cp>ลองมาดู Code ชุดนี้ที่มักจะถูกนำไปใช้ทดสอบไหวพริบในบทสัมภาษณ์กันบ่อยๆ ครับ:\u003C\u002Fp>\u003Cp>JavaScript\u003C\u002Fp>\u003Cpre>\u003Ccode>console.log(\"Start\");\r\n\r\nsetTimeout(() =&gt; {\r\n  console.log(\"Timeout 0s\");\r\n}, 0);\r\n\r\nPromise.resolve().then(() =&gt; {\r\n  console.log(\"Promise\");\r\n});\r\n\r\nconsole.log(\"End\");\r\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch3>สิ่งที่เกิดขึ้นเบื้องหลังแบบ Step-by-Step:\u003C\u002Fh3>\u003Col>\u003Cli>\u003Cp>\u003Cstrong>console.log(\"Start\"):\u003C\u002Fstrong> ถูกดันเข้า Call Stack และแสดงผล \"Start\" ออกมาทันที จากนั้นก็ Pop ออกจาก Stack\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>setTimeout (0ms):\u003C\u002Fstrong> เมื่อทำงานใน Stack มันจะส่ง Callback ไปให้ Web APIs จัดการนับเวลา แม้จะตั้งไว้ 0 วิ แต่มันต้องถูกส่งไปต่อคิวที่ \u003Cstrong>Macrotask Queue\u003C\u002Fstrong> (หรือ Task Queue) เสมอ\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Promise.resolve():\u003C\u002Fstrong> ส่วนของ \u003Ccode>.then()\u003C\u002Fcode> จะถูกส่งไปที่ \u003Cstrong>Microtask Queue\u003C\u002Fstrong> ซึ่งเป็นคิวที่มีลำดับความสำคัญสูงกว่าคิวปกติ\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>console.log(\"End\"):\u003C\u002Fstrong> ทำงานใน Call Stack เป็นลำดับสุดท้ายของ Code ชุดหลัก และแสดงผล \"End\"\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Ch3>ช่วงเวลาตัดสินของ Event Loop:\u003C\u002Fh3>\u003Cp>เมื่อ Call Stack ว่างลง Event Loop จะเริ่มทำงานตามกฎลำดับความสำคัญ (Priority) ดังนี้:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>ตรวจสอบ Microtask Queue ก่อน:\u003C\u002Fstrong> มันจะจัดการงานในคิวนี้ให้หมดเกลี้ยง ดังนั้น Promise จึงถูกดึงกลับมาแสดงผลก่อน\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>ตรวจสอบ Macrotask Queue (Task Queue):\u003C\u002Fstrong> เมื่อ Microtask ว่างแล้ว มันถึงจะไปหยิบงานจากคิวปกติมาทำ นั่นคือ Timeout 0s\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Cp>\u003Cstrong>ผลลัพธ์ที่ได้ (Output):\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Plaintext\u003C\u002Fp>\u003Cpre>\u003Ccode>Start\r\nEnd\r\nPromise\r\nTimeout 0s\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Microtask vs Macrotask: ใครสำคัญกว่ากัน?\u003C\u002Fh2>\u003Cp>ในระบบของ Event Loop คิวงานไม่ได้มีแค่แถวเดียวครับ แต่มันถูกแยกออกเป็น 2 ประเภทใหญ่ๆ ตามลำดับความสำคัญ (Priority) ดังนี้:\u003C\u002Fp>\u003Ch3>1. Microtask Queue (คิวสิทธิพิเศษ)\u003C\u002Fh3>\u003Cp>เป็นคิวที่ Event Loop จะให้ความสำคัญเป็นอันดับแรก หลังจากที่ Call Stack ทำงานปัจจุบันเสร็จสิ้น ระบบจะวิ่งมาเช็คคิวนี้ทันที และต้องทำให้หมดเกลี้ยงก่อนที่จะขยับไปทำอย่างอื่น\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>คำสั่งที่ใช้คิวนี้:\u003C\u002Fstrong> \u003Ccode>Promises\u003C\u002Fcode> (พวก \u003Ccode>.then\u003C\u002Fcode>, \u003Ccode>.catch\u003C\u002Fcode>, \u003Ccode>.finally\u003C\u002Fcode>), \u003Ccode>MutationObserver\u003C\u002Fcode> และใน Node.js คือ \u003Ccode>process.nextTick\u003C\u002Fcode>\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Ch3>2. Macrotask Queue (คิวปกติ)\u003C\u002Fh3>\u003Cp>หรือที่บางครั้งเรียกว่า \u003Cstrong>Task Queue\u003C\u002Fstrong> เป็นคิวสำหรับงานทั่วไปที่รอได้\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>คำสั่งที่ใช้คิวนี้:\u003C\u002Fstrong> \u003Ccode>setTimeout\u003C\u002Fcode>, \u003Ccode>setInterval\u003C\u002Fcode>, \u003Ccode>setImmediate\u003C\u002Fcode>, \u003Ccode>I\u002FO Tasks\u003C\u002Fcode> รวมถึงการดักจับเหตุการณ์จาก User เช่น การคลิก (Click Events)\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Ch3>ลำดับการทำงานที่เกิดขึ้นจริง (The Cycle)\u003C\u002Fh3>\u003Cp>เพื่อให้เห็นภาพลำดับความสำคัญ ลองดูวงจรที่ Event Loop ทำงานใน 1 รอบ (Tick) ครับ:\u003C\u002Fp>\u003Col>\u003Cli>\u003Cp>จัดการงานใน Call Stack จนว่าง\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>จัดการงานทั้งหมดใน Microtask Queue จนหมด (ถ้าในระหว่างทำ มี Microtask ใหม่เกิดขึ้น มันจะทำต่อทันทีจนกว่าจะว่างจริงๆ)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>(เฉพาะใน Browser) ทำการ Render หน้าจอใหม่ (ถ้าถึงรอบการวาด)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>หยิบงานชิ้นเดียวจาก Macrotask Queue ขึ้นไปทำใน Call Stack\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>วนกลับไปเริ่มข้อ 1 ใหม่\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Cblockquote>\u003Cp>\u003Cstrong>Pro Tip:\u003C\u002Fstrong> นี่คือเหตุผลที่ \u003Ccode>setTimeout(..., 0)\u003C\u002Fcode> ไม่เคยทำงานใน 0 วินาทีจริงๆ เพราะมันต้องรอให้ Microtask (เช่นการจัดการข้อมูลจาก API) และรอบการ Render ทำงานให้เสร็จสิ้นก่อน ตัวมันถึงจะได้สิทธิ์ถูกหยิบขึ้นมา\u003C\u002Fp>\u003C\u002Fblockquote>\u003Ch2>ทำไม Developer ถึงต้องใส่ใจเรื่อง Event Loop?\u003C\u002Fh2>\u003Cp>การเข้าใจกลไกนี้ไม่ใช่แค่เพื่อเอาไปตอบคำถามสัมภาษณ์งานครับ แต่มันคือหัวใจสำคัญในการเขียนโปรแกรมให้มีประสิทธิภาพ โดยเฉพาะในประเด็นเรื่อง \u003Cstrong>Blocking the Event Loop\u003C\u002Fstrong> หรืออาการหน้าจอค้าง (UI Freeze) ที่ส่งผลเสียต่อ User Experience โดยตรง\u003C\u002Fp>\u003Ch3>อย่าทำแบบนี้: การยึดครอง Call Stack\u003C\u002Fh3>\u003Cp>เนื่องจาก JavaScript มีเพียง Thread เดียวในการประมวลผล Code และจัดการ UI หากคุณมีคำสั่งที่ใช้เวลาคำนวณนานเกินไปค้างอยู่ใน Call Stack จะทำให้ Event Loop ไม่สามารถไปหยิบงานอื่น (เช่น การคลิก หรือการวาดหน้าจอ) มาทำได้เลย\u003C\u002Fp>\u003Cp>JavaScript\u003C\u002Fp>\u003Cpre>\u003Ccode>\u002F\u002F ตัวอย่าง: การประมวลผลข้อมูลขนาดใหญ่ที่ขวางทางงานอื่น\r\nfunction heavyTask() {\r\n  const start = Date.now();\r\n  while (Date.now() - start &lt; 5000) {\r\n    \u002F\u002F Loop นรกที่ค้างอยู่ใน Stack นาน 5 วินาที\r\n    \u002F\u002F ในช่วงเวลานี้ User จะกดอะไรไม่ได้เลย หน้าเว็บจะค้าง (Not Responding)\r\n  }\r\n  console.log(\"งานหนักเสร็จแล้ว!\");\r\n}\r\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch3>แนวทางการแก้ไขเพื่อประสิทธิภาพสูงสุด\u003C\u002Fh3>\u003Cp>หากคุณเจองานที่ต้องคำนวณหนักๆ (CPU Intensive) มี 2 ทางเลือกที่แนะนำครับ:\u003C\u002Fp>\u003Col>\u003Cli>\u003Cp>\u003Cstrong>ใช้ Web Workers (สำหรับ Browser):\u003C\u002Fstrong> แยกการคำนวณที่ซับซ้อนออกไปรันใน Background Thread อื่นที่ไม่ใช่ Main Thread วิธีนี้จะช่วยให้หน้าจอของคุณยังคงตอบสนอง (Responsive) ได้ตามปกติ แม้จะมีการคำนวณหนักอยู่เบื้องหลังก็ตาม\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>การแบ่งงาน (Task Partitioning):\u003C\u002Fstrong> หากไม่สามารถใช้ Web Workers ได้ ให้แบ่งงานใหญ่ๆ ออกเป็นส่วนเล็กๆ แล้วใช้ \u003Ccode>setTimeout\u003C\u002Fcode> หรือ \u003Ccode>requestAnimationFrame\u003C\u002Fcode> เพื่อ Yield หรือคืนสิทธิ์การควบคุมกลับไปให้ Event Loop ได้มีโอกาสไปจัดการงาน UI หรือ Event อื่นๆ บ้าง ก่อนจะกลับมาทำงานส่วนที่เหลือต่อ\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Ch2>FAQ: คำถามที่พบบ่อยเกี่ยวกับ Event Loop\u003C\u002Fh2>\u003Ch3>1. ถ้าตั้ง setTimeout เป็น 0 (ms) ทำไมมันถึงไม่รันทันที?\u003C\u002Fh3>\u003Cp>\u003Cstrong>คำตอบ:\u003C\u002Fstrong> เพราะ \u003Ccode>setTimeout\u003C\u002Fcode> เป็น Macrotask ครับ แม้จะตั้งเวลาไว้ 0 มิลลิวินาที แต่มันทำได้เพียงแค่ส่งงานไปต่อคิว ใน Macrotask Queue เท่านั้น ตามกฎของ Event Loop มันต้องรอให้ Call Stack ว่าง และรอให้ Microtask Queue (เช่น Promise) ทำงานจนหมดเกลี้ยงก่อน มันถึงจะมีสิทธิ์ถูกดึงกลับมาทำงานครับ\u003C\u002Fp>\u003Ch3>2. Node.js กับ Browser มี Event Loop เหมือนกันไหม?\u003C\u002Fh3>\u003Cp>\u003Cstrong>คำตอบ:\u003C\u002Fstrong> หลักการพื้นฐานเหมือนกันครับ แต่ไส้ในทำงานต่างกันเล็กน้อย Browser ใช้ \u003Cstrong>libevent\u003C\u002Fstrong> (เป็นส่วนหนึ่งของ Chrome) ส่วน Node.js ใช้ library ที่ชื่อว่า \u003Cstrong>libuv\u003C\u002Fstrong> เพื่อจัดการงานที่เป็น I\u002FO นอกจากนี้ใน Node.js จะมีคิวพิเศษเพิ่มเติมอย่าง \u003Ccode>process.nextTick\u003C\u002Fcode> ที่รันก่อน Microtask อื่นๆ อีกด้วยครับ\u003C\u002Fp>\u003Ch3>3. เราสามารถเพิ่ม Thread ให้ JavaScript ได้ไหม?\u003C\u002Fh3>\u003Cp>\u003Cstrong>คำตอบ:\u003C\u002Fstrong> ตัว JavaScript Engine หลักยังคงทำงานแบบ Single Thread ครับ แต่เราสามารถทำสิ่งที่เรียกว่า \u003Cstrong>Parallel Programming\u003C\u002Fstrong> ได้ผ่าน \u003Cstrong>Web Workers\u003C\u002Fstrong> (ใน Browser) หรือ \u003Cstrong>Worker Threads\u003C\u002Fstrong> (ใน Node.js) ซึ่งเป็นการแยก Thread ออกไปประมวลผลต่างหากโดยไม่กวน Main Thread ครับ\u003C\u002Fp>\u003Ch3>4. ทำไมการใช้ Promise ถึงลื่นกว่าการเขียน Loop ยาวๆ?\u003C\u002Fh3>\u003Cp>\u003Cstrong>คำตอบ:\u003C\u002Fstrong> เพราะ Promise ทำงานแบบ \u003Cstrong>Asynchronous\u003C\u002Fstrong> ผ่าน Microtask Queue ครับ มันช่วยให้เราสามารถสั่งงานทิ้งไว้แล้วไปทำอย่างอื่นต่อได้ (Non-blocking) ต่างจากการเขียน Loop ยาวๆ ใน Call Stack ที่จะยึดครอง Thread ไว้เพียงคนเดียวจนกว่าจะเสร็จ (Blocking)\u003C\u002Fp>\u003Ch3>5. Event Loop มีโอกาสหยุดทำงานไหม?\u003C\u002Fh3>\u003Cp>\u003Cstrong>คำตอบ:\u003C\u002Fstrong> มีครับ ถ้าเกิดสิ่งที่เรียกว่า \u003Cstrong>Infinite Loop\u003C\u002Fstrong> ใน Call Stack (เช่น \u003Ccode>while(true) {}\u003C\u002Fcode>) Event Loop จะถูก Block อย่างสมบูรณ์และไม่มีโอกาสได้ไปหยิบงานจาก Queue ไหนมาทำเลย ผลก็คือโปรแกรมจะ Crash หรือหน้าเว็บค้างนั่นเองครับ\u003C\u002Fp>\u003Cp>\u003C\u002Fp>\u003Cdiv data-type=\"horizontalRule\">\u003Chr>\u003C\u002Fdiv>\u003Ch2>สรุป: หัวใจสำคัญของ Event Loop\u003C\u002Fh2>\u003Cp>สรุปสั้นๆ ให้เห็นภาพวงจรชีวิตของ JavaScript ที่รันอยู่ทุกวินาที:\u003C\u002Fp>\u003Col>\u003Cli>\u003Cp>\u003Cstrong>รันงานหลัก:\u003C\u002Fstrong> จัดการงานใน Call Stack ให้เสร็จสิ้น\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>เก็บกวาดงานด่วน:\u003C\u002Fstrong> เคลียร์งานใน Microtask Queue (เช่น Promise) ให้หมดเกลี้ยง\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>อัปเดตหน้าจอ:\u003C\u002Fstrong> Browser ทำการ Render หน้าจอ (ถ้าถึงรอบ)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>ดึงงานคิวถัดไป:\u003C\u002Fstrong> Event Loop หยิบงานจาก Macrotask Queue (เช่น setTimeout) ขึ้นมาทำ\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>วนซ้ำ:\u003C\u002Fstrong> กลับไปเริ่มที่ข้อ 1 ใหม่ตลอดการทำงาน\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Cp>กลไกนี้เองที่ทำให้ JavaScript กลายเป็นภาษาที่มีประสิทธิภาพสูงในด้าน I\u002FO และสามารถจัดการงานจำนวนมากได้พร้อมกันอย่างลื่นไหล แม้จะมีเพียง Thread เดียวก็ตาม\u003C\u002Fp>\u003Cp>หวังว่าบทความนี้จะช่วยให้เพื่อนๆ ชาว \u003Cstrong>Superdev\u003C\u002Fstrong> เข้าใจเบื้องหลังความแรงแบบ Non-blocking ของ JavaScript ได้ชัดเจนขึ้นนะครับ และถ้าไม่อยากพลาดบทความเทคนิคเจาะลึก หรืออัปเดตเทคโนโลยีใหม่ๆ ที่จะช่วยให้การเขียนโปรแกรมของคุณสนุกและโปรยิ่งกว่าเดิม...\u003C\u002Fp>\u003Cp>\u003Cstrong>ฝากกดติดตามพวกเราได้ที่ Superdev Academy\u003C\u002Fstrong> ในทุกช่องทางนะครับ!\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>🔵 Facebook: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener\" class=\"ng-star-inserted\" href=\"https:\u002F\u002Fwww.facebook.com\u002Fsuperdev.academy.th\">\u003Cstrong>Superdev Academy Thailand\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(อัปเดตข่าวสารและบทความใหม่)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>🎬 YouTube: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener\" class=\"ng-star-inserted\" href=\"https:\u002F\u002Fwww.youtube.com\u002F@SuperdevAcademy\">\u003Cstrong>Superdev Academy Channel\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(ติวเข้มแบบวิดีโอ)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>📸 Instagram: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener\" class=\"ng-star-inserted\" href=\"https:\u002F\u002Fwww.instagram.com\u002Fsuperdevacademy\u002F\">\u003Cstrong>@superdevacademy\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(เกร็ดความรู้สั้นๆ และเบื้องหลังการทำงาน)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>🎬 TikTok: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener\" class=\"ng-star-inserted\" href=\"https:\u002F\u002Fwww.tiktok.com\u002F@superdevacademy?lang=th-TH\">\u003Cstrong>@superdevacademy\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(Tips &amp; Tricks ฉบับย่อยง่าย)\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>🌐 Website: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"http:\u002F\u002Fsuperdevacademy.com\">\u003Cstrong>superdevacademy.com\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong> \u003C\u002Fstrong>(คลังบทความและคอร์สเรียนฉบับเต็ม)\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Cp>\u003C\u002Fp>","13y615itqp8_edxqpdfaiv.png","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclblg987654321\u002Flgw0ib2s04k2sry\u002F13y615itqp8_edxqpdfaiv.png","2026-05-07 07:13:31.674Z","",{"keywords":15,"locale":50,"school_blog":60},[16,23,28,32,36,40,45],{"collectionId":17,"collectionName":18,"created":19,"created_by":13,"id":20,"name":21,"updated":22,"updated_by":13},"sclkey987654321","school_keywords","2026-03-04 08:46:37.993Z","v3cb8i6wzv67n9c","Event Loop","2026-04-10 16:13:16.496Z",{"collectionId":17,"collectionName":18,"created":24,"created_by":13,"id":25,"name":26,"updated":27,"updated_by":13},"2026-03-04 08:34:40.816Z","16zodvql5g14o0v","JavaScript Runtime","2026-04-10 16:08:20.077Z",{"collectionId":17,"collectionName":18,"created":29,"created_by":13,"id":30,"name":31,"updated":29,"updated_by":13},"2026-05-06 03:41:04.603Z","du3exohgwved2t1","Microtask",{"collectionId":17,"collectionName":18,"created":33,"created_by":13,"id":34,"name":35,"updated":33,"updated_by":13},"2026-05-06 03:41:10.320Z","84ime09qh36uxtt","Macrotask",{"collectionId":17,"collectionName":18,"created":37,"created_by":13,"id":38,"name":39,"updated":37,"updated_by":13},"2026-05-07 07:05:47.308Z","n033q47b49k4ind","Asynchronous JavaScript",{"collectionId":17,"collectionName":18,"created":41,"created_by":13,"id":42,"name":43,"updated":44,"updated_by":13},"2026-03-04 08:20:42.484Z","vslzz9nvv6n77cx","JavaScript","2026-04-10 16:07:28.339Z",{"collectionId":17,"collectionName":18,"created":46,"created_by":13,"id":47,"name":48,"updated":49,"updated_by":13},"2026-03-04 08:31:35.253Z","r1k7m3354tp5ovr","เรียนเขียนโปรแกรม","2026-04-10 16:07:43.096Z",{"code":51,"collectionId":52,"collectionName":53,"created":54,"flag":55,"id":56,"is_default":57,"label":58,"updated":59},"th","pbc_1989393366","locales","2026-01-22 10:59:55.832Z","twemoji:flag-thailand","s8wri3bt4vgg2ji",true,"Thai","2026-04-10 15:42:46.614Z",{"category":61,"collectionId":62,"collectionName":63,"created":64,"expand":65,"id":79,"slug":80,"updated":81,"views":82},"spm4l1k5bgmhmmt","pbc_2105096300","school_blogs","2026-05-07 07:13:31.441Z",{"category":66},{"blogIds":67,"collectionId":68,"collectionName":69,"created":70,"created_by":13,"id":61,"image":71,"image_alt":13,"image_path":72,"label":73,"name":74,"priority":75,"publish_at":76,"scheduled_at":13,"status":77,"updated":78,"updated_by":13},[],"sclcatblg987654321","school_category_blogs","2026-03-04 08:31:18.590Z","50hyjr6os45_ayazwr5gq7.png","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclcatblg987654321\u002Fspm4l1k5bgmhmmt\u002F50hyjr6os45_ayazwr5gq7.png",{"en":74,"th":74},"Knowledge",0,"2026-03-18 02:25:41.222Z","published","2026-04-25 02:32:14.497Z","m8p00ws3k9oym5h","javascript-event-loop-runtime-explained","2026-05-08 10:04:09.615Z",130,"lgw0ib2s04k2sry",[20,25,30,34,38,42,47],"2026-05-07 07:29:00.800Z","เจาะลึกกลไก Event Loop หัวใจสำคัญที่ทำให้ JavaScript ทำงานแบบ Non-blocking พร้อมสรุปความแตกต่างของ Microtask และ Macrotask แบบ Step-by-Step ที่ Dev ห้ามพลาด!","Event Loop คืออะไร? สรุปกลไก JavaScript Runtime และลำดับการทำงานที่ Dev ต้องรู้","2026-05-08 06:52:28.410Z",1,{"th":80,"en":80}]