דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. JS: ‏‎Uncaught (in promise)‎ - מתי קורה?

JS: ‏‎Uncaught (in promise)‎ - מתי קורה?

מתוזמן נעוץ נעול הועבר תכנות
6 פוסטים 4 כותבים 155 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • yossizY מנותק
    yossizY מנותק
    yossiz
    כתב ב נערך לאחרונה על ידי yossiz
    #1

    ‏‎משהו חדש שלמדתי היום, (מקור)

    מה הפלט בכל אחת מהסְנִיפְּטִים הבאים, ולמה?

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

    1

    (async () => {
      return Promise.reject("נו!‏");
    })().catch(e => {
      console.log('אויש!‏');
    });
    

    2

    (async () => {
      const promise = Promise.reject("נו!‏");
    })().catch(e => {
      console.log('אויש!‏');
    });
    

    3

    (async () => {
      const promise = Promise.reject("נו!‏");
      await promise;
    })().catch(e => {
      console.log('אויש!‏');
    });
    

    4

    (async () => {
      const promise = Promise.reject("נו!‏");
      await new Promise(resolve => setTimeout(resolve, 1000));
      await promise;
    })().catch(e => {
      console.log('אויש!‏');
    });
    

    📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

    תגובה 1 תגובה אחרונה
    4
    • yossizY מנותק
      yossizY מנותק
      yossiz
      כתב ב נערך לאחרונה על ידי
      #2

      ‎הנה התשובות וההסברים

      הקדמה: כללו של דבר, אם אתה לא מטפל ב-rejection של promise תוך כדי אותה איטרציה של ה-event loop - מתקבלת אזהרה של ‏‎Uncaught (in promise)‎ בקונסול.

      איך מטפלים ב-rejection? מצמידים catch ל-promise שמרודז'ק (rejected...).

      מתי נגמר איטרציה של ה-event loop? כאשר לא נשאר יותר קוד סינכרוני להריץ.

      1

      הפלט: אויש!.
      למה? פשוט, כי החזרת את הפרומיס המרודז'ק לקורא של הפונקציה האסינכרונית, והוא הצמיד לו catch תוך כדי אותו איטרציה של ה-event loop.

      2

      הפלט: Uncaught (in promise) נו!‏
      למה? הרי הצמדת catch לפונקציה האסינכרונית?
      התשובה: הפרומיס שהפונקציה האסינכונית מחזירה לא קשורה לפרומיס שיצרת בקריאת Promise.reject‎.

      3

      הפלט: אויש!‏
      כאן מילת הפתח await גורם לשני דברים לקרות.
      א) זו הצהרה שההמשך של הפונקציה היא handler לפרומיס שעליו אתה עושה await. כך שהמשך הקוד שאחרי ה-await מתווספת לשלשלת הפרומיסים.
      ב) הפרומיס שהפונקציה האסינכרונית מחזירה הוא התוצאה של ה-handler.
      אם משהו ישתבש בפרומיס הראשון (Promise.reject("נו!‏")) וזה לא מטופל ב-handler על ידי catch, או אם משהו ישתבש בשני (= כל קוד שאחרי שורת ה-await) זה יגרום לפרומיס המוחזר להיות מרודז'ק, דבר שייתפס על ידי ה-catch שהצמדת לו בתוך אותה איטרציה של ה-event loop.

      4

      הפלט:

      Uncaught (in promise) נו!‏
      אויש!‏
      

      למה?
      כי ה-await הראשון מסיים איטרציה של ה-event loop על ידי קריאה ל-setTimeout. ה-rejection לא טופל בתוך האיטרציה אז מתקבל אזהרה: Uncaught (in promise) נו!‏
      באיטצריה עתידית אתה קורא ל-await promise שכנ"ל גורם לפורמיס המוחזר מהפונקציה להיות משולשל לפרומיס הראשון. ועליו אתה מצמיד catch, ברגע זה טיפלת ב-rejection.

      שים לב למשהו מעניין בקונסול של כרום, ברגע הראשון האזהרה של Uncaught (in promise) נו!‏ מופיע באדום. אחרי שנייה כאשר ה-setTimeout חוזרת ומוצמד handler ל-rejection זה נהפך לשחור.

      📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

      תגובה 1 תגובה אחרונה
      4
      • yossizY מנותק
        yossizY מנותק
        yossiz
        כתב ב נערך לאחרונה על ידי yossiz
        #3

        עוד משהו קטן נוסף:
        אם בדוגמה מס' 4, במקום setTimeout של 1000 היינו עושים timeout של 0, אז לא מקבלים אזהרה של Uncaught (in promise).
        דבר זה אפשר ללמוד גם מזה ש-await עצמו תמיד רץ אחרי שאר הקוד כאילו הרצת אותו על ידי setTimeout של 0, ומכל מקום אם היינו עושים await אחר בלי setTimeout לא היינו מקבלים אזהרה.

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

        📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

        א תגובה 1 תגובה אחרונה
        4
        • א מנותק
          א מנותק
          אהרן
          השיב לyossiz ב נערך לאחרונה על ידי
          #4

          @yossiz
          לא הבנתי את 2.

          dovidD תגובה 1 תגובה אחרונה
          0
          • dovidD מנותק
            dovidD מנותק
            dovid ניהול
            השיב לאהרן ב נערך לאחרונה על ידי
            #5

            @אהרן ב2 הפונקציה לא מחזירה את הפרומייז הפנימי ממילא הcatch שאחריו מקבל void.
            הוא נשאר אם כן ללא טיפול, ללא catch אחריו.
            המשונה זה 4 שמראה שני דברים:
            א. גם עם יש שרשור יפה תחבירית בעצם מאחורי הקלעים לוקחי זמן עד שהcatch נרשם ממילא יש שגיאה
            ב. גם אחרי שנה אפשר לרשום catch לפרומייז שנכשל ממזמן ו"למחוק" את השגיאה (ממש פלאי פלאים...)

            הנה המחשה יותר חזקה: https://codepen.io/dlt/pen/pojYMKR?editors=1010
            אתה יכול לראות בקונסול שהלחיצה על הכפתור יש לה בחינה של חזרה בתשובה...

            מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

            בכל נושא אפשר ליצור קשר dovid@tchumim.com

            י תגובה 1 תגובה אחרונה
            4
            • י מנותק
              י מנותק
              יוסף בן שמעון
              השיב לdovid ב נערך לאחרונה על ידי
              #6

              @dovid אמר בJS: ‏‎Uncaught (in promise)‎ - מתי קורה?:

              אתה יכול לראות בקונסול שהלחיצה על הכפתור יש לה בחינה של חזרה בתשובה...

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

              תגובה 1 תגובה אחרונה
              5

              בא תתחבר לדף היומי!
              • התחברות

              • אין לך חשבון עדיין? הרשמה

              • התחברו או הירשמו כדי לחפש.
              • פוסט ראשון
                פוסט אחרון
              0
              • דף הבית
              • קטגוריות
              • פוסטים אחרונים
              • משתמשים
              • חיפוש
              • חוקי הפורום