תחי ישראל - אין לנו ארץ אחרת

תחי ישראל -אין לנו ארץ אחרת

Async/Await לסנכרון קוד של JavaScript

מחבר:
בתאריך:

ב- JavaScript ביצוע הקוד הוא סינכרוני. כלומר, ניתן לבצע פעולה אחת בכל רגע. אבל ההתנהגות היא א-סינכרונית, ולכן יש לנו תחושה שאנחנו יכולים להריץ כמה בלוקים של קוד במקביל. הודות לתחביר שמאפשר לסקריפט לא להתעכב עד לקבלת התוצאה של אירועים, ובמקום זה לחזור אחר כך, כדי לאסוף את התוצאה. לדוגמה, כשאנחנו שולחים קריאה ב- Ajax, אנחנו לא מחכים עד שהיא תחזור, אלא מבצעים את הטיפול בתוך callback או promise , ובינתיים יתר הסקריפט ממשיך לרוץ.

נוסף ל- callback ול- promise , התחביר החדש שמאפשר את ההתנהגות הא-סינכרונית נקרא Async/Await , וכדאי להכיר אותו כי במהלך השנים הקרובות יותר ספריות ומפתחים יאמצו אותו.

במדריך זה נזכיר בקצרה כיצד נוהגים להקנות ל-JavaScript התנהגות א-סינכרונית באמצעות callbacks ו- promises, ואז נמשיך להסבר על Async/Await.

מדריך async/await javascript

 

קוד א-סינכרוני באמצעות callback

setTimeout נותן לנו דוגמה קלסית לשימוש ב- callback:

window.setTimeout( ()=> console.log('line 1'),100);
console.log('line 2');

והתוצאה היא ששורה 2 מודפסת לפני שורה 1. אתם מוזמנים לנסות בעצמכם.

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

זה עובד גם ללא ציון הזמן שהפונקציה צריכה להמתין בתור הפרמטר השני שמעבירים למתודה:

window.setTimeout(()=> console.log('line 1'));
console.log('line 2'); 

למה? callback!
כי הקוד בתוך ה-callback מבוצע אחרי יתר הסקריפט.

זו תכונה שימושית במיוחד כשרוצים להמתין למידע שמגיע משרת מרוחק. לדוגמה, הבאת מידע ב-Ajax באמצעות jQuery:

jQuery.get('https://phpenthusiast.com/dummy-api', (res) => console.log(res));
// The rest of the script

יתר הסקריפט רץ, במקום לחכות עד שהמידע יחזור, אם בכלל, מהשרת המרוחק.

שירות ה-api בדוגמה, מחזיר מספר אקראי בין 1 ל-6, כמו בהטלת קובייה.

 

קוד א-סינכרוני באמצעות promise

הדרך החדישה יותר להביא מידע משרת מרוחק היא באמצעות המתודה fetch שמחזירה promise, דהיינו אחת משתי תוצאות אפשריות, הצלחה או כישלון.

fetch('https://phpenthusiast.com/dummy-api/')
  .then((res) => console.log(res)) 
  .catch((error) => console.log(error));

הצלחה, שמשמעותה החזרת המידע המבוקש, מטופלת בבלוק then.

ומקרים של שגיאה, מטופלים באמצעות בלוק catch.

אחד היתרונות של שימוש ב- promises הוא שניתן לחבר אותם אחד לשני לשרשרת של promises שרצים אחד אחרי השני. לדוגמה, כדי לחלץ מידע בפורמט JSON שמגיע באמצעות המתודה fetch() , נוסיף לשרשרת את המתודה json() , שגם היא מחזירה promise().

fetch('https://phpenthusiast.com/dummy-api/') 
  .then((res) => res.json()) 
  .then((data) => console.log(data)) 
  .catch((error) => console.log(error))

מעבר לאלגנטיות של התחביר, השגיאות, ולא משנה באיזה מה- promises הם קורות, מטופלות על ידי אותו בלוק catch.

ל- promise ניתן לשרשר את המתודה all() שמחכה לסיומם של מספר אירועים, לדוגמה אם אנחנו רוצים לקבל מידע ממספר מקורות שונים. ובדוגמה שלנו, אנחנו רוצים לקרוא פעמיים לשירות ה- api כדי לחקות הטלה של שתי קוביות:

const api = 'https://phpenthusiast.com/dummy-api/';
let dice1 = fetch(api);
let dice2 = fetch(api);
Promise.all([dice1,dice2])
// …

כדי למצות את המידע באופן יעיל צריך לשלב את המתודה map():

let dice1 = fetch(api);
let dice2 = fetch(api);
Promise
  .all([dice1,dice2])
  .then(responses => Promise.all(responses.map(res => res.json())))
  .then(results => console.log(`And the result is: ${results[0].random},  ${results[1].random}`))
  .catch(()=>console.log('can\'t throw the dices'));

ולאותה תוצאה ניתן להגיע באמצעות תחביר Async/Await.

 

קוד א-סינכרוני באמצעות Async/Await

התחביר של Async/Await הוא פשוט וקריא יותר מאשר promise , והוא משתמש במילות המפתח async ו- await.

מוסיפים את מילת המפתח async לפני הפונקציה ואת מילת המפתח- await בתוך הפונקציה.

const diceThrower = async () => {
    let dice1 = await dice();
}

הפונקציה שלה קורא ה- await מחזירה promise:

const api = 'https://phpenthusiast.com/dummy-api/';
const dice = () => {
    return fetch(api).then(res => res.json());
}

וה- await ממתין שכל הקריאות לשרת יענו כדי להריץ את יתר הקוד:

const diceThrower = async () => {
    let dice1 = await dice();
    let dice2 = await dice();
    console.log(`The result is: ${dice1.random},  ${dice2.random}`);
}

הקוד קריא הרבה יותר, וכדי לטפל בשגיאות נעטוף אותו ב- try…catch:

const diceThrower = async () => {
    try {
        let dice1 = await dice();
        let dice2 = await dice();
        console.log(`The result is: ${dice1.random},  ${dice2.random}`);
    }  catch(err)  {
        console.log(err);	          
   }	
}

זו הדוגמה המלאה:

const api = 'https://phpenthusiast.com/dummy-api/';
const dice = () => {
    return fetch(api).then(res => res.json());
}
  
const diceThrower = async () => {
    try {
        let dice1 = await dice();
        let dice2 = await dice();	
        console.log(`The result is: ${dice1.random},  ${dice2.random}`);	      
    } catch(err) { 
        console.log(err);	    	
    }
}
diceThrower();

מדריכי JavaScript למתקדמים

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

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

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

שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.

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

השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.

הוסף תגובה חדשה

 

 

ענה על השאלה הפשוטה הבאה כתנאי להוספת תגובה:

דג למים הוא כמו ציפור ל...?

 

תמונת המגיב

רועי בתאריך: 09.12.2019

ב"ה
אתר מעולה! ממש מושקע וברור! כל הכבוד! ברוך תהיה!

תמונת המגיב

חזי בתאריך: 06.01.2020

יפה מאוד!
תודה רבה!

תמונת המגיב

מיכל בתאריך: 07.06.2020

הפונקציה fetch היא רק לקריאות http???

תמונת המגיב

אבי בתאריך: 09.08.2022

Thank you!!!

תמונת המגיב

יחיאל בתאריך: 06.09.2022

הסבר מעולה! תודה!

תמונת המגיב

אחמד בתאריך: 13.12.2022

מתמצת וממצה! תודה רבה!