
getSite במודול longcalc מדמים גלישה לשרת מרוחק: מחכים שתי שניות ומחזירים מספר רנדומלי בין 0 ל-99. הפונקציה מחזירה Promise.then. התוצאה היא then בתוך then, והקוד הופך להזחה עמוקה.הטקסט המלא של הדקות הראשונות בהרצאה «בעיית ה-Callback Hell» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
לפעמים קורה מצב שבו אנחנו רוצים לקרוא לפונקציה אסינכרונית והפונקציה האסינכרונית הזאת מחזירה לנו איזושהי תוצאה ואנחנו רוצים לקחת את התוצאה הזאת ולשלוח אותה לפונקציה אסינכרונית אחרת.
זאת אומרת שהפונקציה האסינכרונית השנייה תלויה בתוצאה של הפונקציה האסינכרונית הראשונה ואולי הפונקציה האסינכרונית השנייה גם צריכה להחזיר לנו איזה משהו שאותו אנחנו גם רוצים לשלוח לפונקציה האסינכרונית שלישית או אפילו לפונקציה הראשונה, או שוב פעם לאותה פונקציה.
במצב כזה יש לנו פה קריאות מתוך פונקציות הסינכרוניות לתוך פונקציות הסינכרוניות, והמצב הזה נקרא callback hell. callback hell זה מצב שבו פונקציה קוראת לפונקציה שקוראת לפונקציה, אבל בצורה מאוד לא אלגנטית ומאוד לא יפה בקוד.
אם אנחנו רוצים לראות דוגמה לזה, פה נבנה פונקציה אסינכרונית אחת, נקרא לה כמה פעמים כאשר כל פעם היא תחזיר לנו ערך ואנחנו רוצים להשתמש בערך בשביל לקרוא לה עוד פעם.
בואו ניקח דוגמה שיש לנו איזושהי פונקציה במודול הנפרד long calculation שמבצעת גלישה לשרת מרוחק והפונקציה הזאת תקבל איזשהו url והיא תחזיר לנו בחזרה איזשהו נתון מסוים שאנחנו נגריל סתם איזשהו מספר רנדומלי אבל אנחנו רוצים להשתמש בו בשביל שוב פעם לקרוא ולשלוח לפונקציה אחרת או לאותה פונקציה עם url אחר
בכדי להבין מה זה בדיוק המצב הזה של callback hell וכמובן גם איך לפתור אותו אם אנחנו משתמשים בטכניקה הרגילה של callbacks אין ממש אפשרות לפתור את הcallback hell נניח נשלח פה Error Callback ו-Success Callback.
פה לא תהיה כל כך אפשרות לפתור את הסיטואציה הזאת. אם אנחנו משתמשים עם promise, אנחנו נוכל לראות את הבעיה של ה-callback hell ואחר כך נוכל גם לראות את הפתרון שלה.
אז קודם כל, בואו רגע נחזיר return new promise. ה-promise כמובן אמרנו מקבל פונקציה אחת לסוגריים, הפונקציה האחת שהוא מקבל מקבלת resolve ו-reject, וכאן אנחנו בעצם רוצים לבצע את הקוד שכאילו גולש לשרת מרוחק.
אנחנו כמובן נעשה הדמיה כאילו אנחנו גולשים לשרת מרוחק, ומשהו שלוקח לנו הרבה זמן, נניח שלוש שניות לגלוש לשרת המרוחק. ואז אנחנו אמורים לקבל איזשהו מידע מהשרת המרוחק ולהחזיר אותו.
אז איך אנחנו מבצעים את הגלישה הזאת לשרת המרוחק? אז את הגלישה לשרת המרוחק אנחנו עושים על ידי הדמיה של set timeout, בואו נניח לוקח שלוש שניות.
אין צורך לעשות פה את הלולאה הארוכה הזאת, כי בין כה אנחנו יכולים לראות בשלוש שניות האלה כמשהו שלוקח הרבה זמן. ואז אחרי שהשלוש שניות מסתיימות, אנחנו נגריל איזשהו מספר.
בואו ניקח כאן איזשהו number, ניקח math parse int וניתן לו את math.random כפול 100. בעצם הגרלנו כאן איזשהו מספר רנדומלי, אז אנחנו רוצים עכשיו בהצלחה לדווח אותו.
איך אנחנו מדווחים אותו בהצלחה? ריזולב, והנה המספר דווח. דבר נוסף, בואו נעטוף את זה באיזשהו טריי קאץ'.
אם יש לנו פה איזשהו כישלון, ריצ'קט, ואנחנו רוצים לדווח את השגיאה עצמה שהתרחשה. אז יש לנו פה ממש שימוש בכל מה שאנחנו רואים, האמת בואו נעשה משהו עם ה-URL גם נניח שאנחנו רוצים לעשות 100 ועוד URL ואז יש לנו גם איזשהו שימוש עם ה-URL כדי שהוא לא יהיה באפור כזה כי אנחנו עושים הדמיה כאילו שאנחנו גולשים
לשרת המרוחק הזה שקיבלנו, מקבלים ממנו איזשהו מספר, מדווחים את ההצלחה הזאת, מדווחים את המספר כהצלחה אם זה קורס מאיזושהי סיבה מדווחים כישלון.
מציענו לבנות את הפונקציה האסינכרונית, אבל איפה פה הכל בקהל? כאשר אנחנו קוראים לה, בואו נקרא לה get site, קודם כל יש לנו את ה-long calculation, long calc נקודה, אני שוב רואה ששכחתי, נחשוף אותה החוצה, זאת הסיבה שאנחנו לא רואים אותה שם.
מודול exports, נשים את הפונקציה כאן, ועכשיו היא אמורה להיות ב-long calc get site. דאטה ואנחנו שולחים איזשהו url http://mysite.com לא של השרת הזה לאיזשהו דאטה ותביא לי משם את המספר אוקיי מה מוחזר לנו מפה?
דן וקאץ׳ אז אני נכנס לקאץ׳ ובקאץ׳ סליחה לא לקאץ׳ אני נכנס לדן ובדן אני רוצה לבצע איזושהי פעולה וגם בקאץ׳ אני רוצה לבצע איזושהי פעולה אבל בואו לצורך הפשטות נסיים קודם כל את הקאץ'. בקאץ' כל מה שאני רוצה לעשות זה קיבלתי את ה-error ומה שאני רוצה זה console.log ולהציג את ה-error. נעשה
את זה כמו שתמיד אנחנו עושים בצורה כזאת. console.log ולהציג את ההודעה עצמה. זה מה שאני תמיד רוצה לעשות נניח כרגע בכל מקרה של שגיאה. אבל מה אני רוצה לעשות ב-then?
ב-then אני רוצה לקבל את ה-num ומה אני רוצה לעשות איתו? עוד פעם לבצע קריאה מחדש לפונקציה אסינכרונית אחרת או לאותה פונקציה זה לא משנה אבל לשלוח לה את המספר הזה שהתקבל, את ה-num.
אז בואו נעתיק את כל, האמת כל זה, הופה, טעות גזרתי, c ונדביק את זה פה ועל הפעם נשתמש עם ה-num הראשון הזה, בואו נקרא לו num1 שלא יבלבל אותנו, כאן, ונשלח data עם num1.
הנה השתמשתי עם אותו מספר שנשלח אליי. ועכשיו הפונקציה הזאת, או שהיא תצליח או שהיא תכשל. אם היא תכשל, אני מציג את השגיאה. אם היא תצליח, קיבלתי את המספר.
בואו נקרא לו, שלא יבלבל אותנו, num2, ואני רוצה לבצע שוב פעם גלישה לפונקציה אסינכרונית אחרת או לאותה פונקציה, זה לא משנה, כי אני מדגים את ה-callback hell שיש פה.