async/await ב-JavaScript
במאמר זה נסביר על async/await ב-JavaScript.
YouTube Video
async/await ב-JavaScript
async (ו-await) ב-JavaScript הם תכונות שנועדו להפוך כתיבת פעולות אסינכרוניות לאינטואיטיביות וקריאות יותר. בעזרת זה, ניתן להפחית את המורכבות של פונקציות callback מסורתיות ושל שרשראות Promise, ולכתוב קוד אסינכרוני בצורה שנראית כמו קוד סינכרוני.
פונקציית async
async משמשת להגדרת פונקציה כפונקציה אסינכרונית. פונקציית async תמיד מחזירה אובייקט Promise. בתוך פונקציה המסומנת ב-async, ניתן להשתמש ב-await כדי להמתין לתוצאה של Promise שיחזיר ערך.
תחביר בסיסי של פונקציית async
1async function myAsyncFunction() {
2 // Write asynchronous processing here
3 return 'Result'; // Return a Promise
4}במקרה זה, קריאה לפונקציה myAsyncFunction() מחזירה באופן אוטומטי אובייקט Promise. כאשר ה-Promise נפתר, התוצאה שלו הופכת לערך שהוחזר על ידי 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. על ידי השימוש ב-await, ניתן להשהות את הביצוע עד שה-Promise נפתר ולקבל את תוצאת ה-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, ואז מבצעת פעולות אסינכרוניות נוספות עם התוצאה.
ניהול שגיאות עם 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 מאפשר לתפוס שגיאות שמתרחשות במהלך פעולות אסינכרוניות ומונע קריסה של התוכנית בעת שגיאות.
יתרונות של async/await
בהשוואה לשרשראות Promise מסורתיות, async/await מציע את היתרונות הבאים:.
- קריאות משופרת
- אפשר לכתוב עיבוד אסינכרוני כמו קוד סינכרוני, וכך להימנע מהמורכבות של שרשראות
Promiseושכבות רבות של callback-ים.
- אפשר לכתוב עיבוד אסינכרוני כמו קוד סינכרוני, וכך להימנע מהמורכבות של שרשראות
- נוחות איתור באגים
- מכיוון שזה דומה לקוד סינכרוני, איתור באגים וטיפול בשגיאות הופכים לפשוטים יותר.
- תחזוקה משופרת
- אפשר לכתוב תהליכים אסינכרוניים בצורה פשוטה יותר, מה שמקל על שינוי או עדכון קוד ומשפר את התחזוקה לטווח הרחוק.
דוגמה: שרשרת Promise לעומת 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()פותר מספר Promises בו זמנית ומחזיר את התוצאות שלהן כמערך. הוא ממתין לפתרון כל ה-Promises, ואם אחד מהם נכשל, זה נחשב לכישלון כללי.
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()מחזירה את התוצאה של ההבטחה הראשונה שמתקיימת או נדחית. זה מועיל כאשר ברצונך להגיב לאיזו מהפעולות האסינכרוניות שמסתיימת ראשונה. עם זאת, אם ההבטחה הראשונה נכשלת, השגיאה נתפסת מיד על ידי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()מחכה לכל התוצאות, ללא קשר אם הצליחו או נכשלו. כל תוצאה מוחזרת בצורה של{ status, value }או{ status, reason }, כך שניתן לדעת אילו הבטחות הצליחו ואילו נכשלו.
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()מחזירה רק את התוצאה של ההבטחה הראשונה שהושלמה בהצלחה. חריגה נזרקת רק אם כל ההבטחות נכשלות. ניתן להשתמש בכך כמנגנון נסיונות חוזרים בסביבות שבהן חלק מה-APIs אינם אמינים עד שאחד מצליח.
סיכום
- פונקציית
async: תמיד מחזירה Promise ומשמשת לכתיבת עיבוד אסינכרוני. await: משמש להמתנה לפתרון Promise ולקבלת התוצאה שלו.- טיפול בשגיאות: השתמש ב-
try...catchלטיפול בשגיאות שמתרחשות במהלך עיבוד אסינכרוני. - מספר פעולות אסינכרוניות: באמצעות שיטות כמו
Promise.all(), ניתן להריץ מספר משימות אסינכרוניות במקביל.
async/await הם כלים חזקים לעיבוד אסינכרוני, אז וודא/י להשתמש בהם כדי לפשט לוגיקה אסינכרונית מורכבת.
תוכלו לעקוב אחר המאמר שלמעלה באמצעות Visual Studio Code בערוץ היוטיוב שלנו. נא לבדוק גם את ערוץ היוטיוב.