הבנת Promise ב-JavaScript
Promise הוא אובייקט של JavaScript שבתוכו אנחנו שמים קוד, שמחזיר אחת משתי תוצאות, הצלחה או כישלון.
התחביר של Promise
האובייקט Promise מקבל פונקציה בתור פרמטר, והפונקציה הזו מקבלת שני פרמטרים: resolve ו-reject.
new Promise(function(resolve, reject) {});
ובתחביר מודרני:
new Promise((resolve, reject) => {});
האובייקט Promise מחזיר אחת מ- 2 מתודות:
- resolve - שתקרא במקרה שהקוד הצליח.
- reject - שתקרא במידה והקוד נכשל.
בואו נדגים באמצעות הטלת מטבע:
let flipCoin = new Promise((resolve, reject) => {
// The code
let head = (Math.random() < 0.5);
// Resolve in the case of success
if(head === true){
resolve("Yeah, it's head!");
}
// Otherwise reject
reject("No luck this time!");
});
הקוד משתמש בפונקציה rand של JavaScript כדי להציב ערך אקראי למשתנה head, ובמקרה שהערך של head הוא true ה-Promise קורא למתודה resolve, אחרת נקראת המתודה reject.
אם תריצו את הקוד ייתכן שתתאכזבו כי לא תקבלו תוצאה, וזה מפני שאנחנו צריכים לקרוא ל-Promise, וגם לקלוט את התגובה באמצעות המתודות then ו-catch. המתודה then קולטת את ה-resolve, והמתודה catch קולטת את ה-reject.
כך זה נראה:
flipCoin
.then(fromResolve => console.log(fromResolve))
.catch(fromReject => console.log(fromReject));
בחיי היום-יום אנחנו משתמשים ב- promise עבור קוד א-סינכרוני.
בחיי היום-יום אנחנו משתמשים ב- promise עבור קוד א-סינכרוני. לדוגמה, קריאה ב-ajax ל-API חיצוני או טעינת תמונה ל-DOM. נחקה את זה באמצעות setTimeout שישהה את התגובה.
let flipCoin = new Promise((resolve, reject) => {
let head = (Math.random() < 0.5);
window.setTimeout(() => {
if(head === true){
resolve("Yeah, it's a head!");
}
reject("No luck this time!");
}, 1000);
});
flipCoin
.then(fromResolve => console.log(fromResolve))
.catch(fromReject => console.log(fromReject));
וזו התוצאה:
* האנימציה ממחישה את ההשהיה עד לקבלת התוצאה.
אז מה היה לנו עד עכשיו? תחביר אובייקט ה-Promise עם המתודות reolve ו-reject, והקוד שקולט את התוצאה של ה-promise באמצעות המתודות then ו-catch.
שרשור מתודות
השימוש בתחביר ה-promise הוא מועיל במיוחד במקרים שבהם אנחנו צריכים לחכות שפונקציה אחת תסיים כדי שנוכל להריץ את הפונקציה הבאה בתור. ב-JavaScript קלסי השגנו את המטרה הזו על ידי הכנסת הפונקציות אחת לתוך השנייה. מה שגרם למקרים קשים של "עצי חג מולד מהגיהינום". בואו נדגים את זה באמצעות שלושת השלבים של עבודה על פרויקט בשביל לקוח.
talkWithTheCustomer((input) => {
workOnTheProject((result) => {
deliverOnTime((finalResult) => {
console.log('Finito!');
}, failureCallback);
}, failureCallback);
}, failureCallback);
בגלל שביצוע הפונקציה deliverOnTime תלוי בהשלמת הפונקציה workOnTheProject נמקם את הפונקציה השנייה בתוך הראשונה, וכן הלאה עד שנסיים עם כל הפונקציות שדרושות לנו להשלמת המשימה.
אבל עדיף קוד מודולרי כי הוא קריא יותר וקל יותר לתחזוקה, ואת זה נוכל לעשות באמצעות תחביר ה-Promise:
talkWithTheCustomer(input)
.then(result => workOnTheProject(result))
.then(result => deliverOnTime(result))
.then(finalResult => console.log('Finito!'))
.catch(fromReject => console.log('Error'));
כדי שהקוד יעבוד נתחיל בכתיבת ההבטחות.
הפונקציה talkWithTheCustomer עוטפת את ה-Promise הראשון שיצליח רק במקרה שהערך של input הוא "agree".
let talkWithTheCustomer = (input) => {
return new Promise((resolve, reject) => {
window.setTimeout(() => {
if(input === 'agree') {
resolve("OK");
}
reject("Sorry, non starter");
}, Math.random()*1000);
});
}
שימו לב, חובה להחזיר את ה-Promise באמצעות return אחרת זה לא יעבוד.
עוד טריק קטן שהשתמשתי בו הוא שזמן ההשהיה באמצעות setTimeout נקבע באקראי כדי לחקות את הזמן הלא ידוע עד לקבלת תגובה לקוד א-סינכרוני (לדוגמה, כזה שמגיע מ-API שיושב על שרת מרוחק).
ההבטחה workOnTheProject תצליח במידה והערך של everythingWorked הוא true.
let workOnTheProject = (result) => {
return new Promise((resolve, reject) => {
window.setTimeout(() => {
let everythingWorked = true;
if(everythingWorked) {
resolve(result + " >> Everything works according to plan");
}
reject("Sorry, can't deliver on time");
}, Math.random()*2000);
});
}
כדי לראות את התוצאה, צריך לקרוא ל-promise:
let input = "agree";
talkWithTheCustomer(input)
.then(result => workOnTheProject(result))
.then(finalResult => console.log(`${finalResult} >> The project was delivered!`))
.catch(fromReject => console.log(`Problem: ${fromReject}`)); //
כל עוד ה-promises מתקיימים, הקוד ממשיך ועובר מפונקציה לפונקציה לפי הסדר של השרשור עד לסיום, אבל במקרה שאחת ההבטחות כושלת, הקוד מפסיק, וקופץ למתודה catch שתופסת פיקוד. כדי לראות כיצד זה פועל נסו לשנות את הערך של המשתנה input , ואז תראו שה-catch הוא זה שמגיב עם ההודעה שמספק ה- reject של הפונקציה הראשונה, והפונקציה השנייה בכלל לא רצה.
המתודות all ו-race
אם אנחנו רוצים שכל הפונקציות יסיימו ורק אז להריץ קוד אז נשתמש במתודה all של האובייקט Promise. all מקבלת בתור פרמטר את מערך הפונקציות, ורק בסוף נשרשר את הקוד שצריך לרוץ בתגובה לכך שמערך הפונקציות סיים לרוץ.
Promise
.all([a(), b(), c()])
.then(()=>console.log("All the functions have finished"));
אם אנחנו יכולים להסתפק בזה שרק אחת הפונקציות תסיים לרוץ כדי להריץ את הקוד, אז נשתמש במתודה race של האובייקט Promise.
Promise
.race([a(), b(), c()])
.then(()=>console.log("One of the functions has finished"));
race שימושי כאשר פונים למספר API חיצוניים שעושים את אותה העבודה, ומספיק שאחד מהם מספק את המידע כדי שנוכל להריץ את הקוד שלנו.
גישה עוד יותר מודרנית לטיפול בקוד אסינכרוני היא באמצעות תחביר Async/Await עליו תוכלו לקרוא במדריך.
אהבתם? לא אהבתם? דרגו!
0 הצבעות, ממוצע 0 מתוך 5 כוכבים
המדריכים באתר עוסקים בנושאי תכנות ופיתוח אישי. הקוד שמוצג משמש להדגמה ולצרכי לימוד. התוכן והקוד המוצגים באתר נבדקו בקפידה ונמצאו תקינים. אבל ייתכן ששימוש במערכות שונות, דוגמת דפדפן או מערכת הפעלה שונה ולאור השינויים הטכנולוגיים התכופים בעולם שבו אנו חיים יגרום לתוצאות שונות מהמצופה. בכל מקרה, אין בעל האתר נושא באחריות לכל שיבוש או שימוש לא אחראי בתכנים הלימודיים באתר.
למרות האמור לעיל, ומתוך רצון טוב, אם נתקלת בקשיים ביישום הקוד באתר מפאת מה שנראה לך כשגיאה או כחוסר עקביות נא להשאיר תגובה עם פירוט הבעיה באזור התגובות בתחתית המדריכים. זה יכול לעזור למשתמשים אחרים שנתקלו באותה בעיה ואם אני רואה שהבעיה עקרונית אני עשוי לערוך התאמה במדריך או להסיר אותו כדי להימנע מהטעיית הציבור.
שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.
המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?
השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.