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

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

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. עזרה עם async await

עזרה עם async await

מתוזמן נעוץ נעול הועבר תכנות
28 פוסטים 5 כותבים 641 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • א מנותק
    א מנותק
    אהרן
    כתב ב נערך לאחרונה על ידי
    #1

    אולי הכותרת צריכה להיות: הבנת השגיאה Promise resolver undefined is not a function

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

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

    async function getValue() {
    	let value = 0;
    	let keyes = ['cow', 'deer'];
    	
    	if(any_condition) {
    		await Promise.all( keyes.map( row => {
    			return new Promise((reslove) => {
    				db.get('value', (err, newValue) => {
    					if(err)	console.log(err);
    					
    					value += newValue;
    				});
    				reslove();
    			});
    		}));
    	}
    	return new Promise().reslove(value)
    }
    
    
    תגובה 1 תגובה אחרונה
    0
    • zvizviZ מנותק
      zvizviZ מנותק
      zvizvi
      כתב ב נערך לאחרונה על ידי zvizvi
      #2
      function getValue () {
        let value = 0;
        let keyes = ['cow', 'deer'];
      
        return new Promise((resolve, reject) => {
          if (any_condition) {
            return resolve(Promise.all(keyes.map((row) => {
              return new Promise((resolve, reject) => {
                db.get('value', (err, newValue) => {
                  if (err) console.log(err); // return reject?
                  return resolve(value += newValue);
                });
              });
            })));
          }
          return resolve(value);
        })
          .then((result) => {
            return result;
          });
      }
      
      

      https://zvizvi.xyz

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

        יש שתי טעויות, הבנה והקלדה.
        טעות בהבנה, פונקציית await לא אמורה להחזיר פרומייז אלא ערך ישיר.
        כלומר במקום return new Promise תחזיר סתם return value;

        טעות הקלדה, הreslove ללא פרמטר צריך להיות בתוך הבלוק של הdb.get שורה מתחת לvalue += newValue;

        אגב, במידה וכן היית צריך פרומייז אפשר לכתוב Promise.reslove(value) ללא new.

        הנה קוד עובד:
        https://stackblitz.com/edit/js-d1yhhp

        אני מניח שאתה יודע שאתה יכול לעשות באותה מידה את אותו קוד ללא async וawait אלא שאתה מעדיף ללמוד על הדרך העדכנית יותר.

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

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

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

          @zvizvi לthen האחרון אין משמעות, בכל מקרה אתה מחזיר פרומיז.
          כמו"כ הdb.get מחזיר ערך ישירות (undefined, אלא"כ הנחת שזה פרומייז, שזה מידע שאין לי),
          אז אם אני צודק אתה בעצם לא מחכה לתשובה שלו.

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

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

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

            @dovid אמר בעזרה עם async await:

            @zvizvi לthen האחרון אין משמעות, בכל מקרה אתה מחזיר פרומיז.

            נכון, רק בשביל ההבנה שהכל מגיע לפה.

            @dovid אמר בעזרה עם async await:

            כמו"כ הdb.get מחזיר ערך ישירות (undefined, אלא"כ הנחת שזה פרומייז, שזה מידע שאין לי),

            צודק, תיקנתי.

            https://zvizvi.xyz

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

              @dovid
              ראשית, תודה גדולה על ההשקעה!!

              טעות בהבנה, פונקציית await לא אמורה להחזיר פרומייז אלא ערך ישיר.

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

              כלומר במקום return new Promise תחזיר סתם return value;

              1 לא ברור לי ההקשר ואיך זה מסביר את השורה הקודמת
              2 הסיבה שמספיק להחזיר ערך הינו בגלל שכל מה שאחרי await עטוף בפרומיס?

              אגב, במידה וכן היית צריך פרומייז אפשר לכתוב Promise.reslove(value) ללא new.

              טוב לדעת, תודה!!

              הנה קוד עובד:
              https://stackblitz.com/edit/js-d1yhhp

              תודה!!

              אני מניח שאתה יודע שאתה יכול לעשות באותה מידה את אותו קוד ללא async וawait אלא שאתה מעדיף ללמוד על הדרך העדכנית יותר.

              לא. למעשה זו אותה דילמה כמו ב-await.

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

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

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

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

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

                  @dovid לקחתי את הקוד שלך, וערכתי אותו בצורה שהוא יותר אלגנטי וקריא לדעתי.
                  https://stackblitz.com/edit/js-wcyk6m

                  מעוניין לשמוע חוו"ד אם יש שם טעויות או מקום לעוד שיפורים

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

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

                    @dovid אמר בעזרה עם async await:

                    בשביל המתנה משתמשים בפרומייז בדיוק באותה המידה של הawait.

                    איך אני כותב א"ז בפרומיס
                    אם יש לי התניה

                    if(...) {
                       update from async function
                    }
                    return value
                    

                    כך?

                    if(...) {
                       update from async function
                       reslove(value)
                    }
                    reslove(value)
                    

                    א"כ רציתי להימנע מלהפעיל את reslove בנפרד ל-2 האפשרויות (משפט מאוד).

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

                      @dovid אמר בעזרה עם async await:

                      @אהרן לא הבנתי אותך אבל אתה בודאי לא הבנת אותי.

                      נירגע שניה מחלוקת הציונים ונדון ענינית.

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

                      ההגיון ימצא במידה ורוצים לעשות לתשובה .then()

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

                        @yossiz אתה דבר ראשון "ידעת" שהdb.get זה פרומייז, גם אני נתתי לזה סיכויים אבל אני לא יכול לבנות על זה.
                        שנית אני לא רציתי לשנות דברים בקוד שלא נוגעים לשאלה (מלבד קינוני הפרומייז ששיניתי כדי לשרוד).
                        שלישית, כשיהיה לי זמן אעיין בקוד שלך.

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

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

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

                          @אהרן אמר בעזרה עם async await:

                          נירגע שניה מחלוקת הציונים ונדון ענינית.

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

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

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

                          תגובה 1 תגובה אחרונה
                          0
                          • yossizY מנותק
                            yossizY מנותק
                            yossiz
                            השיב לdovid ב נערך לאחרונה על ידי yossiz
                            #13

                            @dovid אמר בעזרה עם async await:

                            אתה דבר ראשון "ידעת" שהdb.get זה פרומייז

                            לא, כתבתי פונקציה promisifiedDbGet שעוטף את ה-db.get המקורי בפרומייז.

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

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

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

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

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

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

                                @dovid אמר בעזרה עם async await:

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

                                db.get לא מחזיר פרומיס
                                בשביל שPromise.all ימתין שכולם יסתיימו, עטפתי את הקירות לdb בפרומיס.

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

                                  @אהרן אמר בעזרה עם async await:

                                  db.get לא מחזיר פרומיס

                                  באשכול השני כתבת שבלי callback זה מחזיר promise

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

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

                                    @yossiz קראתי, נהדר.
                                    את הreduce יש להחליף ב.join(''), במקרה הזה מדובר בשרשור פשוט וזה בדיוק התפקיד של Array.join.

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

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

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

                                      @yossiz אמר בעזרה עם async await:

                                      @אהרן אמר בעזרה עם async await:

                                      db.get לא מחזיר פרומיס

                                      באשכול השני כתבת שבלי callback זה מחזיר promise

                                      אבל בדוגמא כאן כתבתי עם

                                      db.get('value', (err, newValue) => {
                                      
                                      תגובה 1 תגובה אחרונה
                                      0
                                      • א מנותק
                                        א מנותק
                                        אהרן
                                        השיב לdovid ב נערך לאחרונה על ידי
                                        #19

                                        @dovid אמר בעזרה עם async await:

                                        @yossiz קראתי, נהדר.
                                        את הreduce יש להחליף ב.join(''), במקרה הזה מדובר בשרשור פשוט וזה בדיוק התפקיד של Array.join.

                                        הוא צודק במידה ורוצים ערך מספרי.

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

                                          @dovid
                                          אפי' שקראתי שוב ושוב [ושוב], עדיין לא מסכים עם הביקורת שלא קראתי בעיון. לא חשוב.

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

                                          השאיפה שלי היתה לא להחזיר את הערך בכל א' משני האפשרויות אלא אחרי כל ההתניה, ועם זאת שימתין לעדכון הא-סינכרוני (רק בתנאי שמתבצע עדכון א-סינכרוני)
                                          לכן עטפתי את הפונקציה העדכון הא-סינכרוני עם פרומיס לתוך Promise.all עם הקידומת await ע"מ שכל מה שאחרי העדכון (החזרת הערך) ימתין לסיום כל העדכונים. את הערכים שחזרו מהפרומיס'ס אני לא צריך.

                                          async function getValue() {
                                          	let value = 0;
                                          	let keyes = ['cow', 'deer'];
                                          	
                                          	if(any_condition) {
                                          		await Promise.all( keyes.map( row => {
                                          			return new Promise((reslove) => {
                                          				db.get('value', (err, newValue) => {
                                          					if(err)	console.log(err);
                                          					
                                          					value += newValue;
                                          					reslove();
                                          				});
                                          			});
                                          		}));
                                          	}
                                          	return new Promise().reslove(value);
                                          }
                                          

                                          הטעות שמעלה את השגיאה היא

                                          return new Promise().reslove(value);
                                          

                                          והיא שגויה גם אם נכתוב אותה כפי שמחזירים reslove באופן תקין, כך

                                          return Promise().reslove(value);
                                          

                                          ככל שאני מבין את הסיבה, כיון ש-async function תמיד מחזירה את הערך עם מתודת then (זה לא נקרא שהיא מחזירה פרומיס??)
                                          ואילו אם נחזיר פרומיס, יוצא כאילו אנחנו כותבים כך

                                          reslove(Promise().reslove(value))
                                          

                                          או משהו דומה, שזה שגוי.

                                          כפי ש @dovid כתב:

                                          טעות בהבנה, פונקציית await לא אמורה להחזיר פרומייז אלא ערך ישיר.

                                          ואשלים: אבל רק במידה והוא מקבל פרומיס (=ערך שחוזר מפונקצית פרומיס) הוא יודע להמתין לקבלת ערך א-סינכרורי.

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

                                          שוב תודה ל @dovid @zvizvi @yossiz על הדוגמאות וההסברים המושקעים ומפורטים!

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

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

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

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