เขียน Concurrency ใน TypeScript ด้วย Promise allSettled
การทำงานแบบ concurrency หรือการทำงานพร้อมกันหลายๆ งานที่ต้องใช้เวลานานใน TypeScript สามารถทำได้ง่ายๆ ด้วย Promise.allSettled ซึ่งช่วยให้เราสามารถรัน Promise หลายๆ ตัวพร้อมกันและรับผลลัพธ์ทั้งหมดได้ไม่ว่า Promise ตัวไหนจะสำเร็จหรือไม่สำเร็จก็ตาม

ตัวอย่างการใช้งาน
ในตัวอย่างนี้ เราจะมีฟังก์ชัน main ที่ใช้ Promise.allSettled เพื่อรัน Promise หลายๆ ตัวที่แทนงานที่ต้องใช้เวลานาน เช่นการเรียกใช้ API, การดึงข้อมูลจากฐานข้อมูล, หรือการประมวลผลข้อมูลที่มีขนาดใหญ่
;
การทำงานของ Promise.allSettled
เมื่อเรียกใช้ Promise.allSettled จะได้ผลลัพธ์เป็น PromiseSettledResult<T>[] โดย T คือประเภทข้อมูลที่ Promise ส่งกลับ
;
// PromiseSettledResult<number>[]
โค้ดนี้ใช้ interface PromiseFulfilledResult และ PromiseRejectedResult ในการบอกสถานะของ Promise ว่าสำเร็จหรือไม่สำเร็จ
;
สังเกตุในโค๊ดตรงนี้จะเห็นได้ว่า result จะมี type เป็น PromiseSettledResult<number> ดังนั้นเราสามารถ guard type (ลดความเป็นไปได้ของ Type) นั่นคือ
- ถ้ามี
statusเท่ากับ"fulfilled"หมายความว่า TypeScript จะรู้ว่ามันคือ TypePromiseFulfilledResult<number>อัตโนมัติ ซึ่งก็ึคือมี keyvalueที่มี Type เป็นnumberนั่นเอง - แต่ถ้ามี
statusไม่เท่ากับ"fulfilled"(Else Condition) หมายความว่า TypeScript จะรู้ว่ามันคือ TypePromiseRejectedResult<number>อัตโนมัติ (เพราะมีโอกาสแค่ 2 แบบ ถ้าไม่ใช่แบบแรก ก็จะเป็นแบบที่ 2 ทันที) ซึ่งก็ึคือมี keyreasonที่มี Type เป็นanyนั่นเอง
//... Loop in `results` array then....
if result.status === "fulfilled" else
ตัวอย่างของฟังก์ชันที่รันนาน
ในตัวอย่างนี้ เราจำลองการทำงานที่ใช้เวลานานด้วยฟังก์ชัน longRunningTask ที่ทำการจำลองการทำงานและผลลัพธ์ที่สามารถเป็นไปได้
ผลลัพธ์จะแสดงข้อความเกี่ยวกับการทำงานที่รันนานและผลลัพธ์ของแต่ละงานที่สำเร็จหรือไม่สำเร็จ
ด้วยการใช้ Promise.allSettled ใน TypeScript เราสามารถทำงาน concurrency ได้อย่างมีประสิทธิภาพและปรับให้เหมาะกับลำดับการทำงานที่ต้องการในแต่ละบล็อกของโปรแกรมของเราได้อย่างง่ายดาย
ตัวอย่างการทำงานของโปรแกรม
Task 1 started, will take 4 seconds
Task 2 started, will take 4 seconds
Task 3 started, will take 5 seconds
Task 4 started, will take 4 seconds
Task 5 started, will take 2 seconds
Task 1 in progress, current time: 1 seconds
Task 2 in progress, current time: 1 seconds
Task 3 in progress, current time: 1 seconds
Task 4 in progress, current time: 1 seconds
Task 5 in progress, current time: 1 seconds
Task 5 failed
Task 1 in progress, current time: 2 seconds
Task 2 in progress, current time: 2 seconds
Task 3 in progress, current time: 2 seconds
Task 4 in progress, current time: 2 seconds
Task 1 in progress, current time: 3 seconds
Task 2 in progress, current time: 3 seconds
Task 3 in progress, current time: 3 seconds
Task 4 in progress, current time: 3 seconds
Task 1 finished
Task 2 finished
Task 4 failed
Task 3 in progress, current time: 4 seconds
Task 3 failed
--------------------------------------------------
All tasks finished
Task 1 took 4 seconds
Task 2 took 4 seconds
Task 3 failed with error: Task 3 failed
Task 4 failed with error: Task 4 failed
Task 5 failed with error: Task 5 failed