Async/await ใน TypeScript

Async/await ใน TypeScript

บทความนี้อธิบายเรื่อง async/await ใน TypeScript

YouTube Video

Async/await ใน TypeScript

ใน TypeScript, คำสำคัญ async ใช้สำหรับอธิบายการทำงานแบบอะซิงโครนัสอย่างย่อ และมีพฤติกรรมคล้ายคลึงกับไวยากรณ์ async/await ของ JavaScript ฟังก์ชัน async ได้รับการออกแบบมาเพื่อทำให้การจัดการฟังก์ชันที่คืนค่า Promises เข้าใจง่ายขึ้น

พื้นฐานของฟังก์ชัน async

ฟังก์ชันที่ประกาศด้วยคำสำคัญ async จะคืนค่า Promise เสมอ ตัวอย่างพื้นฐานมีดังนี้:

1async function fetchData(): Promise<string> {
2    return "Data received";
3}
4
5fetchData().then((data) => console.log(data)); // "Data received"

ในตัวอย่างนี้ เนื่องจากฟังก์ชัน async คืนค่า Promise เสมอ ค่ารีเทิร์นถูกรีโซลฟ์โดยอัตโนมัติด้วย Promise.resolve กล่าวอีกนัยหนึ่ง "Data received" จะกลายเป็น Promise<string> และถูกจัดการเป็นการดำเนินการแบบอะซิงโครนัส

คำสำคัญ await

คำสำคัญ await สามารถใช้ได้เฉพาะภายในฟังก์ชัน async เท่านั้น สิ่งนี้ช่วยให้สามารถหยุดและรอผลลัพธ์ของ Promise ก่อนที่จะดำเนินการฟังก์ชันต่อไปได้

ในตัวอย่างต่อไปนี้ การประมวลผลแบบอะซิงโครนัสโดยใช้ fetch เขียนโดยใช้ async/await

 1async function getUserData() {
 2    try {
 3        const response = await fetch("https://codesparklab.com/json/example.json");
 4        const data = await response.json();
 5        console.log(data);
 6    } catch (error) {
 7        console.error("Error fetching user data:", error);
 8    }
 9}
10
11getUserData();

ในตัวอย่างนี้ await ถูกใช้เพื่อรอการเสร็จสิ้นของ Promise ที่คืนค่าโดยฟังก์ชัน fetch และผลลัพธ์ถูกกำหนดให้ตัวแปร response นอกจากนี้ ผลลัพธ์ของ response.json() ยังถูกคอยด้วย await

การจัดการข้อผิดพลาดด้วย async/await

ข้อผิดพลาดที่เกิดขึ้นระหว่างการประมวลผลแบบอะซิงโครนัสสามารถจับได้โดยใช้ไวยากรณ์มาตรฐาน try...catch หากเกิดข้อผิดพลาดที่ส่วน await ข้อผิดพลาดนั้นจะถูกจัดการในบล็อก catch

 1async function fetchDataWithErrorHandling() {
 2    try {
 3        const response = await fetch('https://invalid.codesparklab.com/');
 4        if (!response.ok) {
 5            throw new Error(`HTTP error! status: ${response.status}`);
 6        }
 7        const data = await response.json();
 8        console.log(data);
 9    } catch (error) {
10        console.error("Fetch error:", error);
11    }
12}
13
14fetchDataWithErrorHandling();

ในตัวอย่างข้างต้น ผลลัพธ์ของฟังก์ชัน fetch ถูกคอยโดยใช้ await และหากเกิดข้อผิดพลาด มันจะถูกจัดการด้วย try...catch

ข้อดีของ async/await

  1. การประมวลผลแบบอะซิงโครนัสที่เข้าใจง่าย: การใช้ async/await ทำให้การไหลของโค้ดเข้าใจง่ายกว่าการใช้เชนของ Promise (then หรือ catch) และสามารถเขียนให้อยู่ในรูปแบบคล้ายกับการประมวลผลแบบซิงโครนัส

  2. การจัดการข้อผิดพลาดที่ง่ายดาย: การใช้ try...catch ทำให้การจัดการข้อผิดพลาดในกระบวนการอะซิงโครนัสง่ายขึ้น สามารถเขียนโค้ดให้อ่านง่ายขึ้นกว่าการใช้เชนของ Promise

ค่าที่คืนโดยฟังก์ชัน async

ฟังก์ชัน async จะคืนค่าเป็น Promise เสมอ ดังนั้น แม้จะไม่มีการคืนค่า Promise อย่างชัดเจน ก็สามารถดำเนินการแบบอะซิงโครนัสได้โดยใช้คีย์เวิร์ด async

1async function example() {
2    return 42;
3}
4
5example().then((result) => console.log(result)); // 42

ในโค้ดด้านบน คืนค่าตัวเลขซิงโครนัส 42 แต่เนื่องจากอยู่ในฟังก์ชัน async จึงถูกแปลงเป็น Promise.resolve(42) โดยอัตโนมัติ

การดำเนินงานตามลำดับของฟังก์ชันอะซิงโครนัส

เมื่อดำเนินการฟังก์ชันอะซิงโครนัสหลายฟังก์ชันต่อเนื่องกัน คุณสามารถใช้ await เพื่อควบคุมลำดับ

 1async function fetchData(url: string): Promise<any> {
 2    try {
 3        const response = await fetch(url);
 4        return await response.json();
 5    } catch (error) {
 6        console.error("Error fetching user data:", error);
 7    }
 8}
 9
10async function fetchData1(): Promise<any> {
11    return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15    return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function processData() {
19    const data1 = await fetchData1();
20    console.log(data1);
21
22    const data2 = await fetchData2();
23    console.log(data2);
24}
25
26processData();

ในตัวอย่างนี้ fetchData2 จะทำงานหลังจากรอให้ fetchData1 เสร็จสิ้น เรื่องนี้อ่านง่ายกว่าการใช้ Promise chain

การดำเนินงานแบบขนาน

หากต้องการดำเนินการแบบอะซิงโครนัสพร้อมกัน คุณสามารถใช้ Promise.all เพื่อจัดการกับ Promises หลายตัวพร้อมกัน

 1async function fetchData(url: string): Promise<any> {
 2    try {
 3        const response = await fetch(url);
 4        return await response.json();
 5    } catch (error) {
 6        console.error("Error fetching user data:", error);
 7    }
 8}
 9
10async function fetchData1(): Promise<any> {
11    return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15    return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function fetchMultipleData() {
19    const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
20    console.log(data1);
21    console.log(data2);
22}
23
24fetchMultipleData();

ในกรณีนี้ fetchData1 และ fetchData2 จะทำงานพร้อมกัน และกระบวนการจะดำเนินต่อไปหลังจากทั้งสองเสร็จสิ้น วิธีนี้ช่วยให้จัดการกับการดำเนินงานแบบอะซิงโครนัสหลายรายการได้อย่างมีประสิทธิภาพ

สรุป

  • ฟังก์ชัน async จะคืนค่าเป็น Promise และโดยการใช้คีย์เวิร์ด await คุณสามารถรอผลของการดำเนินงานแบบอะซิงโครนัสได้
  • โดยการใช้ try...catch การจัดการข้อผิดพลาดในกระบวนการอะซิงโครนัสจะง่ายขึ้น
  • โดยการใช้ Promise.all เป็นไปได้ที่จะดำเนินการแบบอะซิงโครนัสหลายรายการพร้อมกัน

async/await มีการใช้อย่างแพร่หลายใน TypeScript และ JavaScript เนื่องจากสามารถอธิบายการดำเนินงานอะซิงโครนัสได้ง่ายขึ้น

คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย

YouTube Video