PlusMagi's Blog By Pitt Phunsanit เทคโนโลยี TypeScript: การตรวจสอบข้อผิดพลาดใน await/async

TypeScript: การตรวจสอบข้อผิดพลาดใน await/async

ในโลกของการพัฒนาซอฟต์แวร์สมัยใหม่ การดำเนินการแบบไม่พร้อมกัน (Asynchronous Operations) เช่น การเรียก API ข้ามเครือข่าย หรือการทำงานกับฐานข้อมูล เป็นหัวใจสำคัญที่ทำให้แอปพลิเคชันมีประสิทธิภาพและตอบสนองได้ดี ฟีเจอร์ `async`/`await` ใน TypeScript จึงเข้ามาช่วยให้เราสามารถจัดการโค้ดเหล่านี้ได้อย่างคล้ายกับการเขียนเชิง Synchronous ทำให้โครงสร้างโปรแกรมอ่านง่ายขึ้นอย่างมาก อย่างไรก็ตาม ความสะดวกสบายนี้ก็มาพร้อมความท้าทายในการจัดการข้อผิดพลาด เมื่อเกิดปัญหาใด ๆ ขึ้นระหว่างรอผลลัพธ์ของ Promise เราจำเป็นต้องเข้าใจกลไกพิเศษเพื่อรับประกันว่าแม้ส่วนหนึ่งของระบบจะล้มเหลว ระบบโดยรวมจะไม่หยุดชะงัก

หลักการจับ Error ด้วย try…catch สำหรับ Async/Await

เมื่อใช้คำสั่ง await โค้ดของเรากำลัง ‘ระงับ’ การทำงานจนกว่าค่าสัญญาว่าจะเสร็จสิ้น (Promise) จะถูก resolve หาก Promises นั้นมีการปฏิเสธ (Reject) นั่นหมายถึงมันถือว่าเป็น Exception ซึ่งเป็นจุดที่เราจะต้องอาศัยบล็อกควบคุม

try...catch เพื่อทำการตรวจจับและการบำบัดแก้ไข ข้อแตกต่างที่นักพัฒนาใหม่มักสับสนคือ แม้ว่า asynchronous operation กำลังเกิดขึ้น แต่ตัว JavaScript Runtime Engine ยังคงรันโค้ดในขอบเขตเดียวกัน ดังนั้นจึงทำให้การวาง block ของ try...catch รอบๆ คำสั่ง await มีประสิทธิภาพสูงสุด

  • Try Block: บรรจุชุดของการเรียกใช้งาน Asynchronous ที่เราคาดหวังให้สำเร็จ
  • Catch Block: ทำหน้าที่รับผิดชอบข้อความหรือ Object exception ใด ๆ ที่เกิดจากการ Reject Promise ในช่วงเวลาที่อยู่ใน Try Block ได้อย่างแม่นยำและทันท่วงที

โครงสร้าง Code ตัวอย่างเพื่อป้องกัน Failure

พิจารณาจากสถานการณ์สมมติในการดึงข้อมูลผู้ใช้สองขั้นตอนพร้อมกัน ถ้าหากการเรียก API ครั้งแรกล้มเหลว เราไม่ต้องการให้โปรแกรมดำเนินการไปขอรายละเอียดของผู้ใช้อีกครั้ง เพราะจะนำไปสู่ Error ซ้อน:

async function fetchUserData(userId: string): UserProfile {   // การทำงานที่เราต้องควบคุม   try {   const user = await getUserDetailsApi(userId); // อาจ reject ตรงนี้   if (!user) throw new Error(