Async/await ใน JavaScript
ในบทความนี้ เราจะอธิบายเกี่ยวกับ async/await ใน JavaScript
YouTube Video
Async/await ใน JavaScript
async (และ await) ใน JavaScript เป็นฟีเจอร์ที่ออกแบบมาเพื่อทำให้การเขียนการดำเนินการแบบ asynchronous ง่ายและอ่านได้เข้าใจมากขึ้น ด้วยการใช้งานนี้ คุณสามารถลดความซับซ้อนของฟังก์ชัน callback แบบดั้งเดิมและเชนของ Promise และเขียนโค้ดอะไซครอนัสให้ดูเหมือนโค้ดซิงโครนัสได้
ฟังก์ชัน async
async ใช้เพื่อกำหนดฟังก์ชันให้เป็นฟังก์ชันแบบ asynchronous ฟังก์ชัน async จะคืนค่าเป็น Promise เสมอ ภายในฟังก์ชันที่ระบุด้วย async, คุณสามารถใช้ await เพื่อรอผลลัพธ์ของ Promise ที่จะถูกส่งกลับมา
ไวยากรณ์เบื้องต้นของฟังก์ชัน async
1async function myAsyncFunction() {
2 // Write asynchronous processing here
3 return 'Result'; // Return a Promise
4}ในกรณีนี้ การเรียก myAsyncFunction() จะคืนค่าเป็นออบเจกต์ Promise โดยอัตโนมัติ เมื่อ Promise ถูก resolved, ผลลัพธ์ของมันจะกลายเป็นค่าที่ส่งกลับโดย return
ตัวอย่าง: ฟังก์ชัน async เบื้องต้น
1async function greet() {
2 return 'Hello, World!';
3}
4
5greet().then((message) => {
6 console.log(message); // Displays "Hello, World!"
7});await
await ใช้เพื่อรอ Promise ที่จะถูก resolved ด้วยการใช้ await, คุณสามารถหยุดการดำเนินการชั่วคราวจนกว่า Promise จะถูก resolved และได้รับผลลัพธ์ของ Promise await สามารถใช้ได้เฉพาะภายในฟังก์ชัน async เท่านั้น
ตัวอย่าง: วิธีการใช้ await
1async function fetchData() {
2 // Wait for the result of the Promise
3 const data = await fetch('https://codesparklab.com/json/example.json');
4 // Wait for the asynchronous operation to complete
5 const jsonData = await data.json();
6 // Retrieve and display the data
7 console.log(jsonData);
8}
9
10fetchData();ในตัวอย่างด้านบน จะรอ Promise ที่ถูกคืนค่าโดยฟังก์ชัน fetch ด้วย await, จากนั้นดำเนินการแบบ asynchronous เพิ่มเติมโดยใช้ผลลัพธ์นั้น
การจัดการข้อผิดพลาดด้วย async/await
หากเกิดข้อผิดพลาดภายในฟังก์ชัน async, ข้อผิดพลาดนั้นจะถูกมองว่าเป็น reject ของ Promise คุณสามารถใช้คำสั่ง try...catch เพื่อจัดการข้อผิดพลาด
ตัวอย่าง: การจัดการข้อผิดพลาด
1async function fetchData() {
2 try {
3 // Invalid URL
4 const data = await fetch('https://invalid.codesparklab.com/');
5 const jsonData = await data.json();
6 console.log(jsonData);
7 } catch (error) {
8 // Catch the error
9 console.error('Failed to fetch data:', error);
10 }
11}
12
13fetchData();การใช้บล็อก try...catch ช่วยให้คุณจับข้อผิดพลาดที่เกิดขึ้นระหว่างการดำเนินการแบบ asynchronous, ป้องกันไม่ให้โปรแกรมหยุดทำงานเมื่อเกิดข้อผิดพลาด
ข้อดีของ async/await
เมื่อเปรียบเทียบกับเชนของ Promise แบบดั้งเดิม async/await มีข้อดีดังต่อไปนี้:
- เพิ่มความเข้าใจง่ายของโค้ด
- สามารถเขียนการประมวลผลแบบอะไซครอนัสให้เหมือนโค้ดซิงโครนัสได้ ช่วยหลีกเลี่ยงความซับซ้อนของเชน
Promiseและ callback ที่ซ้อนกันลึก
- สามารถเขียนการประมวลผลแบบอะไซครอนัสให้เหมือนโค้ดซิงโครนัสได้ ช่วยหลีกเลี่ยงความซับซ้อนของเชน
- ดีบักง่ายขึ้น
- เนื่องจากลักษณะโค้ดคล้ายกับโค้ดซิงโครนัส จึงทำให้การดีบักและจัดการข้อผิดพลาดง่ายขึ้น
- บำรุงรักษาโค้ดได้ง่ายขึ้น
- สามารถเขียนกระบวนการทำงานแบบอะไซครอนัสได้อย่างง่ายดาย ทำให้แก้ไขหรือเปลี่ยนแปลงโค้ดได้ง่ายขึ้นและช่วยให้บำรุงรักษาได้ดีในระยะยาว
ตัวอย่าง: Promise chain กับ async/await
ลองเปรียบเทียบโค้ดที่ใช้เชน Promise กับโค้ดที่ใช้ async/await
1// Code using Promise chains
2function fetchDataPromise() {
3 fetch('https://codesparklab.com/json/example.json')
4 .then((response) => response.json())
5 .then((data) => {
6 console.log(data);
7 })
8 .catch((error) => {
9 console.error('Failed to fetch data:', error);
10 });
11}
12
13// Code using async/await
14async function fetchDataAsync() {
15 try {
16 const response = await fetch('https://codesparklab.com/json/example.json');
17 const data = await response.json();
18 console.log(data);
19 } catch (error) {
20 console.error('Failed to fetch data:', error);
21 }
22}ดังที่เห็น การใช้ async/await จะช่วยให้เขียนกระบวนการทำงานแบบอะไซครอนัสในลักษณะเชิงเส้นได้ ทำให้โค้ดอ่านง่ายขึ้น
ดำเนินการหลายกระบวนการแบบอะซิงโครนัสพร้อมกัน
ด้วยการผสมผสาน Promise.all() หรือ Promise.race() กับ await, คุณสามารถดำเนินการหลายกระบวนการแบบอะซิงโครนัสพร้อมกันและจัดการผลลัพธ์ของพวกมันรวมกัน
Promise.all()
1async function fetchMultipleData() {
2 try {
3 const [data1, data2] = await Promise.all([
4 fetch('https://codesparklab.com/json/example1.json'),
5 fetch('https://codesparklab.com/json/example2.json')
6 ]);
7 const jsonData1 = await data1.json();
8 const jsonData2 = await data2.json();
9 console.log(jsonData1);
10 console.log(jsonData2);
11 } catch (error) {
12 console.error('Failed to fetch data:', error);
13 }
14}
15
16fetchMultipleData();Promise.all()จะจัดการ Promise หลายตัวพร้อมกันและคืนผลลัพธ์เป็นอาเรย์ มันจะรอจนกว่า Promise ทั้งหมดจะถูกจัดการ และหากมีอันใดอันหนึ่งล้มเหลว จะถือว่าล้มเหลวทั้งหมด
Promise.race()
1async function fetchFastestData() {
2 try {
3 const fastestResponse = await Promise.race([
4 fetch('https://codesparklab.com/json/example1.json'),
5 fetch('https://codesparklab.com/json/example2.json')
6 ]);
7 const jsonData = await fastestResponse.json();
8 console.log('Fastest data:', jsonData);
9 } catch (error) {
10 console.error('Fetch error:', error);
11 }
12}
13
14fetchFastestData();Promise.race()จะคืนค่าผลลัพธ์ของ Promise ตัวแรกที่เสร็จสิ้นไม่ว่าจะสำเร็จหรือถูกปฏิเสธก็ตาม เหมาะสำหรับกรณีที่คุณต้องการตอบสนองกับการดำเนินการแบบอะซิงโครนัสที่เสร็จสิ้นก่อน อย่างไรก็ตาม หาก Promise ตัวแรกล้มเหลว ข้อผิดพลาดจะถูกจับโดยcatchในทันที
Promise.allSettled()
1async function fetchWithAllSettled() {
2 const results = await Promise.allSettled([
3 // This URL will success
4 fetch('https://codesparklab.com/json/example1.json'),
5 // This URL will fail
6 fetch('https://invalid.codesparklab.com/')
7 ]);
8
9 results.forEach((result, index) => {
10 if (result.status === 'fulfilled') {
11 const url = result.value.url;
12 console.log(`Request ${index + 1} succeeded:`, url);
13 } else {
14 const reason = result.reason;
15 console.warn(`Request ${index + 1} failed:`, reason);
16 }
17 });
18}
19
20fetchWithAllSettled();Promise.allSettled()จะรอผลลัพธ์ของ ทุก Promise โดยไม่คำนึงถึงว่าจะสำเร็จหรือล้มเหลว ผลลัพธ์แต่ละรายการจะถูกส่งกลับมาในรูปแบบ{ status, value }หรือ{ status, reason }ช่วยให้คุณทราบว่า Promise ใดสำเร็จและ Promise ใดล้มเหลว
Promise.any()
1async function fetchAnySuccessful() {
2 try {
3 const firstSuccessful = await Promise.any([
4 // This URL will fail
5 fetch('https://invalid.codesparklab.com/'),
6 // This URL will success
7 fetch('https://codesparklab.com/json/example1.json')
8 ]);
9 const jsonData = await firstSuccessful.json();
10 console.log('First successful response:', jsonData);
11 } catch (error) {
12 console.error('All fetch requests failed:', error);
13 }
14}
15
16fetchAnySuccessful();Promise.any()จะคืนค่าผลลัพธ์ของ Promise ตัวแรกที่สำเร็จเท่านั้น จะเกิดข้อผิดพลาดก็ต่อเมื่อ Promise ทั้งหมดล้มเหลวเท่านั้น สามารถใช้เป็นกลไกการลองใหม่ในสภาพแวดล้อมที่บาง API ไม่เสถียร จนกว่าจะมีอันใดอันหนึ่งสำเร็จ
สรุป
- ฟังก์ชัน
async: จะคืนค่าเป็น Promise เสมอและใช้สำหรับเขียนการประมวลผลแบบอะซิงโครนัส await: ใช้เพื่อรอให้ Promise ถูกจัดการและรับผลลัพธ์ของมัน- การจัดการข้อผิดพลาด: ใช้
try...catchเพื่อจัดการข้อผิดพลาดที่เกิดขึ้นระหว่างการประมวลผลแบบอะซิงโครนัส - การดำเนินการแบบอะซิงโครนัสหลายรายการ: โดยใช้วิธีต่าง ๆ เช่น
Promise.all()คุณสามารถเรียกใช้งานแบบอะซิงโครนัสหลายงานพร้อมกันได้
async/await เป็นเครื่องมือที่ทรงพลังสำหรับจัดการการประมวลผลแบบอะซิงโครนัส, ดังนั้นอย่าลืมใช้มันเพื่อช่วยลดความซับซ้อนของลอจิกอะซิงโครนัส
คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย