מחלקת 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 בערוץ היוטיוב שלנו. נא לבדוק גם את ערוץ היוטיוב.