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

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

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

async ב - forEach

מתוזמן נעוץ נעול הועבר תכנות
23 פוסטים 4 כותבים 1.5k צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • מנצפךמ מנותק
    מנצפךמ מנותק
    מנצפך
    כתב ב נערך לאחרונה על ידי מנצפך
    #2

    אסביר את הבעיה.
    אני מקבל מה ORM רשומות מה DB.
    אני רוצה לעשות מניפולציה על כל רשומה, להוסיף לה פרטים נוספים מה DB.
    (sum של משהו).
    קבלת הנתונים הנוספים מתבצעת ב await. מה שקורה שהפונקציה ממשיכה הלאה ומחזירה לקליינט את הנתונים בלי התוספת המבוקשת.
    זו בעיה קלאסית של סינכרון ב JS.

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

      אתה רוצה שהקליינט יקבל רשימה כשהכל יסתיים?
      או שכל רשומה שמסתיימת נשלחת אליו?

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

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

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

        כשהכל מסתיים.

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

          אל תשתמש עם forEach.
          תעשה map שמחזיר עבור כל שורה async של העדכון, משהו כזה:

          var tasks = rows.map(async function(row){
            return await updateRow(row);
          });
          

          אחרי זה תמתין לסיום כולם ע"י Promise.all:

          Promise.all(tasks).then(function(newlist){
            //החזרה ללקוח
            console.log(newlist)  ;
          });
          

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

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

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

            @dovid זה עובד מעולה!!
            אבל אני מבין שזה קצת טריקי. לא?

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

              @מנצפך אמר בasync ב - forEach:

              @dovid זה עובד מעולה!!
              אבל אני מבין שזה קצת טריקי. לא?

              ממש לא, זה לפי הספר.

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

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

              תגובה 1 תגובה אחרונה
              2
              • zvizviZ מנותק
                zvizviZ מנותק
                zvizvi
                כתב ב נערך לאחרונה על ידי zvizvi
                #8

                @מנצפך אמר בasync ב - forEach:

                אבל אני מבין שזה קצת טריקי. לא?

                זה טריקי.

                https://zvizvi.xyz

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

                  @zvizvi אמר בasync ב - forEach:

                  @מנצפך אמר בasync ב - forEach:

                  אבל אני מבין שזה קצת טריקי. לא?

                  זה טריקי.

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

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

                    @dovid אמר בasync ב - forEach:

                    אל תשתמש עם forEach.
                    תעשה map שמחזיר עבור כל שורה async של העדכון, משהו כזה:

                    var tasks = rows.map(async function(row){
                      return await updateRow(row);
                    });
                    

                    אחרי זה תמתין לסיום כולם ע"י Promise.all:

                    Promise.all(tasks).then(function(newlist){
                      //החזרה ללקוח
                      console.log(newlist)  ;
                    });
                    

                    נסיתי לחקות את ההמתנה לשרת ע"י setTimeOut כך

                    var tasks = [1,2,3].map(async function(row){
                      return await setTimeout(() => row*2, Math.random() )
                    });
                    
                    Promise.all(tasks).then(function(newlist){
                      console.log(newlist)  ;
                    });
                    

                    אבל זה גם מחזיר מספרים לא נכונים וגם המספרים שחוזרים מצטברים וגדלים בכל הרצה.
                    מה לא נכון?

                    תגובה 1 תגובה אחרונה
                    0
                    • מנצפךמ מנותק
                      מנצפךמ מנותק
                      מנצפך
                      כתב ב נערך לאחרונה על ידי
                      #11

                      @אהרן אולי צריך לעשות row*=2.

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

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

                        var tasks = rows.map(function(row){
                           return updateRow(row);
                        });
                        

                        השארה של הasync+await והמרה של הPromise.all ללולאה רגילה על הtasks (שבעצם לא תכיל מערך פרומייז אלא מערך rows), גם תעבוד, אבל אני חושש שזה לא יעיל (תלוי באופן בו הawait עובד, אני הולך לבדוק את זה).

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

                        אז בשביל Promise.all תכתוב ככה:

                        var tasks = [1,2,3].map(function(row){
                          return new Promise((reslove) => 
                             setTimeout(() => reslove(row*2), Math.random())
                          );
                        });
                        
                        Promise.all(tasks).then(function(newlist){
                          console.log(newlist)  ;
                        });
                        

                        בשביל async+await ככה:

                        var values = [1,2,3].map(async function(row){
                          return await new Promise((reslove) => 
                             setTimeout(() => reslove(row*2), Math.random())
                          );
                        });
                        
                        console.log(values)  ;
                        

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

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

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

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

                          אקיצער, אין טעם לעשות async+await בפונקציית הmap. אלא יש להשתמש בפוקנציה רגיל שמחזירה פרומייז ואח"כ לעשות Promise.all.

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

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

                          א תגובה 1 תגובה אחרונה
                          1
                          • מנצפךמ מנותק
                            מנצפךמ מנותק
                            מנצפך
                            כתב ב נערך לאחרונה על ידי
                            #14

                            @dovid אצלי זה כבר עובד תקופה מאז שכתבת את הקוד הראשון.
                            מעניין איך עשיתי בסוף.

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

                              @מנצפך אמר בasync ב - forEach:

                              @dovid אצלי זה כבר עובד תקופה מאז שכתבת את הקוד הראשון.
                              מעניין איך עשיתי בסוף.

                              נכון, הוא יעבוד, אבל הוא מסורבל.
                              צריך להסיר את הasync+await.

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

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

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

                                @dovid אמר בasync ב - forEach:

                                אקיצער, אין טעם לעשות async+await בפונקציית הmap. אלא יש להשתמש בפוקנציה רגיל שמחזירה פרומייז ואח"כ לעשות Promise.all.

                                כלומר כך:

                                var values = [1,2,3,4,5,6,7,8,9].map(function(row){
                                  return new Promise((reslove) => 
                                     setTimeout(() => reslove(row*2), Math.random()*2000)
                                  );
                                });
                                
                                
                                Promise.all(values).then(function(newlist){
                                  console.log(newlist)  ;
                                });
                                

                                יש לך מושג אם הפונקציה שבתוך ה-map רצה על כל האיטרציות במקביל או שהם ממתינים אחת על השניה?

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

                                  @אהרן אמר בasync ב - forEach:

                                  יש לך מושג אם הפונקציה שבתוך ה-map רצה על כל האיטרציות במקביל או שהם ממתינים אחת על השניה?

                                  זה

                                  console.time('test1')
                                  var values = [1,2,3,4,5,6,7,8,9].map(function(row){
                                    return new Promise((reslove) => {
                                       var rndom = Math.random()*2000;
                                       console.log(rndom)  ;
                                       setTimeout(() => reslove(row*2), rndom)
                                    });
                                  });
                                  ​
                                  ​
                                  Promise.all(values).then(function(newlist){
                                    console.timeEnd('test1')
                                    console.log(newlist);
                                  });
                                  

                                  מוכיח שבמקביל.

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

                                    מה אתם אומרים על זה:

                                    function asyncMap(task) {
                                    	return Promise.all(
                                    		this.map(function(row){
                                    			return new Promise((reslove) => {
                                    				task(row, reslove);
                                    			});
                                    		})
                                    	);
                                    }
                                    
                                    Array.prototype.asyncMap = asyncMap;
                                    
                                    [1,2,3,4,5,6,7,8,9].asyncMap( function(row, reslove){
                                    	setTimeout(() => reslove( row*2), Math.random()*3000);
                                    })
                                    .then(function(newlist){
                                      console.log(newlist);
                                    });
                                    
                                    תגובה 1 תגובה אחרונה
                                    2
                                    • dovidD מנותק
                                      dovidD מנותק
                                      dovid ניהול
                                      כתב ב נערך לאחרונה על ידי
                                      #19

                                      @אהרן יפה מאוד!
                                      תתקן בtask שבתוך הפרומייז להוסיף return או שתמחק את הסוגריים המסולסלות והנקודה פסיק.

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

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

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

                                        @dovid אמר בasync ב - forEach:

                                        להוסיף return

                                        בשביל מה?

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

                                          @אהרן אמר בasync ב - forEach:

                                          @dovid אמר בasync ב - forEach:

                                          להוסיף return

                                          בשביל מה?

                                          צודק, טעיתי בקריאת הקוד.

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

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

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

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

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

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