Skip to content

Node.js | ข้อควรระวังการใช้งาน Async/Await กับ forEach()

Last updated on August 6, 2018

หลายคนเข้าใจว่า function ใดๆ ที่รับ callback function เป็น parameter จะทำงานแบบ async เสมอ ซึ่งเป็นความเข้าใจที่ผิด (ผมก็เคยเข้าใจแบบนั้น) แต่บาง function ก็ทำงานแบบ synchrous นะครับ เช่น forEach()  ที่เป็น built-in function ของ collection ใน JavaScript ก็ทำงานแบบ synchronous เช่นกัน ดู spec ที่นี่

สมมุติว่าผมต้องการ ใช้ async/await กับ forEach() ผมก็สามารถใช้งาน async กับ callback function ที่ส่งเข้าไป เพื่อให้ใช้ await ได้เช่นกัน ดูตัวอย่างโค้ดนี้ครับ

const numbers = [1, 2, 3]

async function retNum(n) {
  return n
}

function display(numbers) {
  const collection = []
  
  numbers.forEach(async (n) => {
    collection.push(await retNum(n))
  })
  
  return collection
}

console.log(display(numbers))

คิดว่าจะได้ผลลัพธ์ยังไงครับ? จะได้แบบนี้หรือเปล่า?

1
2
3

คำตอบคือไม่ใช่!!! ผลลัพธ์ของโปรแกรมคือ

[]

ทำไมจึงเป็นแบบนี้ไปได้ … นั่นก็เพราะ callback function ที่ส่งเข้าไปใน forEach() มันกลายเป็น async function ไปแล้ว การทำงานของมันคือมันจะนำไปใส่ queue รอไว้เพื่อรอรอบการทำงานของ event loop เสร็จเมื่อไหร่ค่อยส่งผลลัพธ์กลับไป โดยไม่รอให้เสร็จก่อน โดยข้ามไปทำคำสั่งต่อไปซึ่งก็คือ return โดยค่าของ collection = [] จึงได้ผลลัพธ์เป็น [] ส่งออกไปแสดง

เวลาใช้ async/await ก็ระวังกันนิดนึงครับ

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.