การทำงานกับงานที่ต้องใช้เวลา หรือรอเพื่อให้ได้ค่านั้นกลับมา เช่นในบทความนี้ คือ การเรียก API หลายๆ ตัวพร้อมกันใน JavaScript เราจะสามารถจัดการได้อย่างมีประสิทธิภาพด้วย Promise.all()
โดย Promise.all()
เป็นฟังก์ชันที่ช่วยให้เราสามารถรัน promises หลายตัวพร้อมกัน และจะ return ค่าเมื่อ promises ทุกตัวทำงานเสร็จและไม่มี Error ใดๆ ซึ่งถ้าตัวใดตัวหนึ่งเกิด Error ขึ้นมา ก็จะเข้าสู่ error handler ทันที
Promise.all() คืออะไร?
Promise.all()
เป็นฟังก์ชันที่รับ promises หลายตัวและรอจนกว่าทั้งหมดจะทำงานเสร็จ (resolve) หรือเมื่อหนึ่งในนั้นเกิดข้อผิดพลาด (reject) จะถูกจับและจัดการใน .catch()
โดยทันที
ตัวอย่างการใช้:
ในโค้ดตัวอย่างข้างต้น:
- เราเรียก API สามตัวโดยใช้
axios.get()
- เมื่อ API ทั้งสามสำเร็จ (resolve) ข้อมูลจะถูกส่งไปยัง
.then()
โดยจัดเก็บไว้ในตัวแปรresponse1
,response2
, และresponse3
- หากมี API ตัวใดตัวหนึ่งล้มเหลว (reject) ระบบจะเข้าสู่
.catch()
และจัดการข้อผิดพลาด
ตัวอย่างการใช้งาน Promise.all() กับ API หลายเส้น
สมมติว่าเรามี API 3 เส้นที่ต้องเรียกพร้อมกัน ได้แก่:
- API สำหรับดึงข้อมูล
/posts
- API สำหรับดึงข้อมูล
/users
- API สำหรับดึงข้อมูล
/albums
เราสามารถใช้ Promise.all()
กับ axios เพื่อเรียก API ทั้ง 3 เส้นนี้ได้ดังนี้:
คำอธิบาย:
axios.get()
: ใช้สำหรับเรียก API แต่ละตัว ซึ่งจะคืนค่าเป็น promisePromise.all([fetchPosts, fetchUsers, fetchAlbums])
: รัน API ทั้งสามตัวพร้อมกัน และรอให้ทุกตัวทำงานเสร็จสิ้นก่อนเข้าสู่ .then() เพื่อจัดการกับผลลัพธ์postsResponse.data
,usersResponse.data
,albumsResponse.data
: Axios จะเก็บข้อมูล response ไว้ใน property ชื่อ data เราจึงสามารถดึงข้อมูลมาใช้งานได้.catch()
: จัดการกับข้อผิดพลาด หากมี API ตัวใดล้มเหลว ระบบจะเข้าสู่.catch()
โดยไม่ต้องรอให้ API ตัวอื่นเสร็จสิ้น
ข้อควรระวังในการใช้ Promise.all()
แม้ว่า Promise.all()
จะช่วยให้เราสามารถรันงานหลายงานพร้อมกันได้ แต่หากมีงานใดงานหนึ่งเกิดข้อผิดพลาด (reject) มันจะหยุดการทำงานและเข้าสู่ .catch()
ทันที และไม่รอให้งานอื่นเสร็จสิ้น ตัวอย่างเช่น:
ในตัวอย่างนี้ API /albums_that_does_not_exist
จะล้มเหลว และ Promise.all()
จะเข้าสู่ .catch()
ทันที ดังนั้น API ที่สำเร็จ (เช่น /posts
และ /users
) จะไม่ได้ประมวลผลต่อ
สรุป
Promise.all()
เป็นเครื่องมือที่มีประสิทธิภาพเมื่อเราต้องการจัดการกับหลายๆ งานที่ต้องทำพร้อมกัน โดยเฉพาะการเรียก API หลายเส้นในครั้งเดียว อย่างไรก็ตาม เราต้องระวังในกรณีที่มี promise ใด promise หนึ่งเกิดข้อผิดพลาด เพราะมันจะทำให้ฟังก์ชันเข้าสู่ .catch()
ทันทีโดยไม่รอให้ตัวอื่นทำงานเสร็จสมบูรณ์
การใช้งาน axios ร่วมกับ Promise.all()
ทำให้โค้ดของเราดูเรียบง่ายขึ้นและช่วยให้การจัดการงาน asynchronous มีประสิทธิภาพมากยิ่งขึ้น