מחלקת Promise בג׳אווהסקריפט

מחלקת Promise בג׳אווהסקריפט

במאמר זה נסביר על מחלקת Promise בג׳אווהסקריפט.

YouTube Video

Promise

מחלקת Promise היא מחלקה לטיפול בפעולות אסינכרוניות. היא מטפלת בתוצאות במקרה שהפעולה מצליחה או בשגיאות במקרה של כישלון. בעבר השתמשו בפונקציות callback כאשר היה צורך להמתין לפעולה אסינכרונית שתסתיים, אבל Promise הופך זאת לברור וחזק יותר.

1const promise = new Promise((resolve, reject) => {
2    setTimeout(() => resolve("Done!"), 1000);
3});
4
5// Displays "Done!" after 1 second
6promise.then(result => console.log(result));
  • הקוד הזה הוא דוגמה לתהליך אסינכרוני שמציג "בוצע!" לאחר שנייה אחת.
    • ראשית, אובייקט Promise חדש נוצר באמצעות new Promise. הארגומנט הוא פונקציה שמקבלת שני callback-ים: resolve עבור הצלחה ו-reject עבור כישלון.
    • נעשה שימוש ב-setTimeout כדי לקרוא ל-resolve() לאחר שנייה אחת.
    • המתודה then() של אובייקט ה-promise מחכה לסיום ומציגה את התוצאה.

מבנה בסיסי

Promise הוא אובייקט שבסופו של דבר יסתיים או ב-הצלחה או ב-כישלון.

 1const promise = new Promise((resolve, reject) => {
 2    // Asynchronous operation
 3    // Flag indicating whether the operation was successful
 4    const success = true;
 5
 6    if (success) {
 7        resolve('Operation successful!');
 8    } else {
 9        reject('An error occurred');
10    }
11});
  • במקרה של הצלחה, מופעלת הפונקציה resolve().
  • במקרה של כישלון, מופעלת הפונקציה reject().

לאובייקט Promise יש שלושה מצבים.

1promise
2    .then((result) => {
3        console.log(result);
4    })
5    .catch((error) => {
6        console.error(error);
7    })
  • ממתין
    • התהליך האסינכרוני עדיין לא הסתיים.
  • הושלם
    • התהליך האסינכרוני הצליח, והתוצאה הוחזרה על ידי resolve(). התוצאה מתקבלת באמצעות מתודת then().
  • נדחה
    • התהליך האסינכרוני כשל, ושגיאה נגרמה באמצעות reject(). השגיאה מתקבלת באמצעות המתודה catch().

שיטות then() ו-catch()

באמצעות Promise ניתן להגדיר מה לעשות כשהפעולה האסינכרונית מסתיימת. לצורך כך, ניתן להשתמש בשיטות then() ו-catch().

then()

1const promise = new Promise((resolve, reject) => {
2    resolve('Operation successful!');
3});
4
5promise.then((result) => {
6    console.log(result);  // "Operation successful!"
7});
  • שיטת then() מגדירה פונקציה שתיקרא כאשר ה-Promise מצליח.

catch()

1const promise = new Promise((resolve, reject) => {
2    reject('An error occurred');
3});
4
5promise.catch((error) => {
6    console.error(error);  // "An error occurred"
7});
  • שיטת catch() מגדירה פונקציה שתיקרא כאשר ה-Promise נכשל.

שיטת finally()

 1const promise = new Promise((resolve, reject) => {
 2    resolve('Operation successful!');
 3});
 4
 5promise
 6    .then((result) => {
 7        console.log(result);
 8    })
 9    .catch((error) => {
10        console.error(error);
11    })
12    .finally(() => {
13        console.log('The operation has completed');
14    });
  • שיטת finally() מגדירה קוד שיבוצע בסיום הפעולה, ללא קשר אם ה-Promise הצליח או נכשל.

שרשרת then()

then() מחזיר Promise חדש, כך שניתן לשרשר את ה-then() הבא.

 1const promise = new Promise((resolve, reject) => {
 2    setTimeout(() => {
 3        resolve(1);
 4    }, 1000);
 5});
 6
 7promise
 8    .then(result => {
 9        console.log(result); // 1
10        return result + 1;
11    })
12    .then(result => {
13        console.log(result); // 2
14        return result + 1;
15    })
16    .then(result => {
17        console.log(result); // 3
18    })
19    .catch(error => {
20        console.error(error.message); // Something went wrong
21    });
  • בקוד זה, ה-resolve() הראשוני מעביר את הערך 1, וכל ערך שמוחזר מ-then עובר ל-then הבא.
  • באמצעות catch(), ניתן לטפל בכל שגיאה שמתרחשת בשרשרת במקום אחד.

דוגמה מעשית

לדוגמה, משתמשים לעיתים קרובות ב-Promises כדי להביא נתונים משרת. בואו נסתכל על דוגמה באמצעות ה-API של fetch().

 1fetch('https://codesparklab.com/json/example.json')
 2    .then(response => {
 3        if (!response.ok) {
 4            throw new Error('Network error');
 5        }
 6        return response.json();
 7    })
 8    .then(data => {
 9        console.log(data);
10    })
11    .catch(error => {
12        console.error('Error:', error);
13    });
  • בקוד הזה, מכיוון ש-fetch() מחזיר Promise, משתמשים ב-then() כדי לעבד את הנתונים לאחר קבלת תגובה מהשרת. שגיאות מתבצעות באמצעות catch().

טיפול במספר Promises

Promise.all()

כדי להריץ מספר Promises במקביל ולהמשיך רק אם כולם מצליחים, השתמש ב-Promise.all().

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.resolve(2);
 3const promise3 = Promise.resolve(3);
 4
 5Promise.all([promise1, promise2, promise3])
 6    .then((results) => {
 7        console.log(results);  // [1, 2, 3]
 8    })
 9    .catch((error) => {
10        console.error('Error :', error);
11    });
  • then() נקרא רק אם כל ה-Promises מצליחים. catch() נקרא אם אפילו אחד נכשל.

Promise.allSettled()

אם ברצונך להפעיל מספר Promise-ים במקביל ולקבל את כל התוצאות ללא קשר להצלחה או לכישלון, השתמש ב-Promise.allSettled().

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.reject("Failed");
 3const promise3 = Promise.resolve(3);
 4
 5Promise.allSettled([promise1, promise2, promise3])
 6    .then((results) => {
 7        results.forEach(result => console.log(result));
 8        // [
 9        //   { status: 'fulfilled', value: 1 },
10        //   { status: 'rejected', reason: 'Failed' },
11        //   { status: 'fulfilled', value: 3 }
12        // ]
13    });
  • then() נקרא כאשר כל ה-Promise-ים הסתיימו (הושלמו או נדחו). כל תוצאה כוללת את מאפיין ה-status ('fulfilled' או 'rejected'). גם אם חלקם נכשלים, זה לא משפיע על הפעולות האחרות.

Promise.race()

Promise.race() מחזירה את התוצאה של ה-Promise שמסתיים ראשון, בין אם זה בהצלחה או בכישלון.

1const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'First'));
2const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'Second'));
3
4Promise.race([promise1, promise2]).then((result) => {
5    console.log(result);  // "First"
6});
  • כמו בדוגמה זו, התוצאה של ה-Promise הראשון שהושלם מוחזרת.

קשר עם async/await

שימוש בתחביר async/await מאפשר לכתוב Promises בצורה אינטואיטיבית יותר. פונקציית async תמיד מחזירה Promise, ו-await מחכה שה-Promise ייפתר.

 1async function fetchData() {
 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 :', error);
 8    }
 9}
10
11fetchData();

באמצעות async/await בדרך זו, ניתן לכתוב פעולות אסינכרוניות כמו קוד סינכרוני, מה שהופך את הקריאה לקלה יותר.

סיכום

  • Promise הוא אובייקט לטיפול בהצלחות או כשלונות של פעולות אסינכרוניות.
  • טפל בהצלחות של פעולות באמצעות then() ובשגיאות באמצעות catch().
  • finally() מגדיר קוד שמורץ בסוף ללא קשר להצלחה או כישלון.
  • ניתן לטפל במספר Promises בבת אחת באמצעות Promise.all() או Promise.race().
  • async/await הוא תחביר לכתיבת Promises בצורה פשוטה יותר.

תוכלו לעקוב אחר המאמר שלמעלה באמצעות Visual Studio Code בערוץ היוטיוב שלנו. נא לבדוק גם את ערוץ היוטיוב.

YouTube Video