חוקי הפורום

js throw false


  • תכנות

    האם הקוד שלהלן תקין?
    האם יש בעיה להשתמש ב throw בכדי שהקוד שלאחריו לא יופעל?
    בהמשך לדיון שהיה לי כאן https://tchumim.com/post/58832
    יצא לי שוב לבדוק את הנושא ואז הגעתי לפיתרון פשוט, והיות ואף אחד לא כתב לי את זה שם, ברצוני לדעת האם זה לא נכון/תיקני לעשות כך, וא"כ למה.
    מה אומרים מומחי JS.

    router.get('/test', function (req, res) {
        var user_id = read('id');
        console.log(user_id);
        var name = read('name');
        console.log(name);
        fetch(`http://aaa.com?name=${name}&id=${id}`);
        res.end('id_list_message=נשלח בהצלחה');
    
    });
    
    function read(var_name){
        if (query[var_name]){
            return query[var_name];
        }else{
            res.end('read=הקש זהות=id');
            throw false;
        }
    }
    


  • @חוקר

    מה אומרים מומחי JS.

    זה לא כל כך נושא למומחי JS אלא למומחי תכנות. מבחינת JS זה נראה תקין. מבחינת תכנות נראה לי שזה לא אלגנטי. הייעוד של exceptions הוא למצב חריג. זה לא נועד כדרך לשלוט בזרימה של התוכנה.
    (סתם הערה, בצורה שבה כתבת פונקציית read מחוץ לפונקציה שקורא לה, יוצא ש-res הוא undefined)


  • תכנות

    @yossiz אמר בjs throw false:

    (סתם הערה, בצורה שבה כתבת פונקציית read מחוץ לפונקציה שקורא לה, יוצא ש-res הוא undefined)

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


  • תכנות

    רק tוסיף שבעצם כבר ציינתי שם פיתרון לבעיה עצמה, אך היא סתם מנכססת להוסיף לאחר כל כל משתנה שאני דורש מהמאזין להוסיף תנאי שיחזיר את הפונקציה
    עיין כאן
    https://tchumim.com/post/60070
    הנקודה היא שאני רוצה מתוך פונקציה חיצונית לגרום לקטע הקוד שלמעלה ממנו לעצור, הוי אומר שהקוד בהמשך הrouter יעצור
    ואת זה מצאתי ב throw



  • זה בקיצור הנקודה:
    Don't use exceptions for control flow
    https://softwareengineering.stackexchange.com/a/189225

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

    לא מקובל לעשות את זה בשום שפה (נדמה לי... 🤔) כי הקוד לא קריא כאשר הזרימה של הפונקציה מושפעת מפונקציה חיצונית.
    נראה לי שיש פתרונות יותר אלגנטיות כאן, אבל המחשבה על ה-API של ימות גורמת לי לכאבי בטן... 🤢 אז אשאיר את העבודה לאחרים...

    בעצם @dovid ו-@magicode המליצו מאוד על משהו, מה לא טוב בפתרון שלהם?

    (כמובן מותר לך להשתמש בשיקול הדעת שלך במקרים חריגים ולכתוב קוד לא קריא...)



  • @yossiz
    אם הוא יקבל את התוצאה בפונקציה הראשית
    ואם שווה false רק אז הוא יפעיל את הthrow
    האם זה נחשב יותר טוב?



  • @nigun לא הבנתי כוונתך. אם הוא יקבל את התוצאה השלילית בפונקציה הראשית אין צורך לזרוק חריגות, אפשר לעשות return בשלום ובשלווה.


  • תכנות

    @yossiz אמר בjs throw false:

    בעצם @dovid ו @magicode המליצו מאוד על משהו, מה לא טוב בפתרון שלהם?

    הנקודה היא פשוטה הפיתרון שהציעו לי כאן
    https://tchumim.com/post/59303
    היא לטעמי רחוקה ממה שאני צריך.
    כי אני מבצע פעולות רבות לפי הנתונים שהמאזין הקיש
    אני עושה כאן דוגמא בסיסית אבל שמשקפת מאוד חזק את צורת העבודה שלי:

        let name = read(req, res, 'f-הקלט את שמך', 'name', VOICE);
        let status = read(req, res, 't-בחר את הסטטוס האישי, לבחור הקש אחד לאברך הקש שתיים לתתלמיד חיידר הקש שלוש', 'status', MENU + '12');
        if (status === '1'){
            let yeshiva = read(req, res, 't-הקלט את שם הישיבה ולסיום הקש סולמית', 'yeshiva', VOICE);
            database.insertSQL({'name' : name,'yeshiva' : yeshiva}, 'bachurim').then(id => {
                say('t-נרשמת בהצלחה המספר האישי שלך הינו.n-' + id);
            })
        }else if (status === '2'){
            let isuk = read(req, res, 't-אברך כולל הקש אחד, נהנה מיגיע כפיו הקש שתיים', 'isuk', MENU + '12');
            let data = {'name' : name, 'isuk' : isuk};
            if (isuk === '1'){
                data['kolel'] = read(req, res, 't-הקלט את שם הכולל ולסיום סולמית', 'kolel', VOICE);
            }else if (isuk === '2'){
                data['work'] = read(req, res, 't-הקלט את שם מקום העבודה', 'work', VOICE);
    
            }
            database.insertSQL(data, 'avrechim').then(id => {
                say('t-נרשמת בהצלחה המספר האישי שלך הינו.n-' + id);
            })
        }else if (status === '3'){
            //...
        }
    

    בקוד ניתן לראות ראשית למה חשוב לי לכתוב את המשתנים בזה אחר זה לפי הסדא שאני צריך אותם ולא בתוך לולאה.
    ומצד שני ניתן לראות למה חשוב שהפונקציה read תסיים את ריצת המשך הקוד, כי כפי שזה בנוי בימות המשיח בקריאה הראשונה אין לי שום ערך, ואז אני נתן פקודה לימות שייתן לי ערך name ובקריאה השניה כבר יש לי את הname ואז אני צריך את הסטטוס האישי ולאחר מכן נתונים לפי התנאים.
    אם הקוד לא יעצור, השרת ימשיך את הקוד ואז ינסה להכניס לד"ב את הרישום למרות שהפרטים שם הם undefined וזה ייכשל ויגרום לשגיאה או לרישום לא נכון.
    בPHP לעומת זאת זה היה מאוד פשוט, כאשר ה read מקבל ערך שהוא לא קיים והוא דורש מימות המשיח להחזיר את הערך, אז עושים exit() וחסל, השרת סיים לעבוד כעת.
    ב nodejs נתקעתי, כי השרת כן ממשיך.
    אז יש פיתרון, לעשות כך:

            let yeshiva = read(req, res, 't-הקלט את שם הישיבה ולסיום הקש סולמית', 'yeshiva', VOICE);
            if (typeof yeshiva !== 'string'){
                return false;
            }
            database.insertSQL({'name' : name,'yeshiva' : yeshiva}, 'bachurim').then(id => {
                say('t-נרשמת בהצלחה המספר האישי שלך הינו.n-' + id);
            })
    

    (אני יודע שניתן גם לעשות אחרת:

            let yeshiva = read(req, res, 't-הקלט את שם הישיבה ולסיום הקש סולמית', 'yeshiva', VOICE);
            if (typeof yeshiva === 'string'){
                database.insertSQL({'name' : name,'yeshiva' : yeshiva}, 'bachurim').then(id => {
                    say('t-נרשמת בהצלחה המספר האישי שלך הינו.n-' + id);
                })
            }
    

    אבל אז יש יכול להיווצר מידי הרבה הזחות, ולפעמים על כלום כמו בדוגמא כאן:
    https://tchumim.com/post/59315
    ולכן יותר קל לעשות תנאי שעוצר מאשר תנאי להמשיך)
    ולמעשה הפיתרון מסרבל, כי זה מוסיף שורות קוד מיותרות ולא תמיד אני זוכר להשים אותו, והיה לי כבר בעיה במערכת של תרומות שאספתי נתונים ובצעתי חיוב מול שרת API של חברת סליקה, ושכחתי להשים return false והחיוב בוצע מיד לאחר קליטת נתון הCVV לפני מספר התשלומים (בעצם זה ביצע כל פעם ניסון חיוב, רק שהוא נכשל מצד חברת האשראי, אך מספר התשלומים שהינו אופצינאלי כבר לא היה מעכב, וזה בוצע כעיסקא בתשלום אחד).
    ולכן אני כן רוצה משהו שמזכיר את ה exit של PHP.
    וכאן מצאתי פתאום את הפתרון של ה throw false.
    ולכן חשוב לדעת האם באן שהוא אני ימצא את עצמי שזה לא תיקני ולא טוב.


  • תכנות

    @yossiz אמר בjs throw false:

    זה בקיצור הנקודה:
    Don't use exceptions for control flow
    https://softwareengineering.stackexchange.com/a/189225

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

    The use case that exceptions were designed for is "I just encountered a situation that I cannot deal with properly at this point, because I don't have enough context to handle it, but the routine that called me (or something further up the call stack) ought to know how to handle it."

    The secondary use case is "I just encountered a serious error, and right now getting out of this control flow to prevent data corruption or other damage is more important than trying to continue onward."

    If you're not using exceptions for one of these two reasons, there's probably a better way to do it.

    ובתרגום:

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

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

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

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

    אני צודק?



  • @חוקר המקרה שלך לא בדיוק דומה. מדובר אצלך במשהו צפוי שהוא חלק מהזרימה של התהליך. וגם אתה לא משתמש בחריגה כדי לשלוח את השגיאה למעלה ב-stack לטיפול, אלא כדי להפסיק את הריצה של כל ה-stack עם חסכון של שורות קוד.
    בכל מקרה אין איסור לכתוב קוד כזה... ייתכן שהמקרה שלך מקום לגטימי לשימוש לא נכון בחריגות... כמו שיש מקרים שזה לגיטימי להשתמש ב-GOTO. (אם היה GOTO ב-JS הייתי ממליץ אולי להשתמש בזה)


  • תכנות

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



  • אגב, נדמה לי ש-@MusiCode עבד הרבה כדי למצוא פתרון בדיוק לבעיה שלך, והוא עשה ספרייה לשימוש נוח ב-API של ימות המשיח, מן הסתם הוא ישמח אם תעיף מבט על הספרייה שלו.
    https://github.com/MusiCode1/yemot-router


  • תכנות

    @yossiz אמר בjs throw false:

    אגב, נדמה לי ש-@MusiCode עבד הרבה כדי למצוא פתרון בדיוק לבעיה שלך, והוא עשה ספרייה לשימוש נוח ב-API של ימות המשיח, מן הסתם הוא ישמח אם תעיף מבט על הספרייה שלו.
    https://github.com/MusiCode1/yemot-router

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


  • תכנות

    @dovid
    יש לך עמדה בנושא?



  • @WWW אמר בjs throw false:

    לטעמי תמשיך עם החריגות

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


  • תכנות

    בפוסט כאן ובגובות הקטנות על הפוסט נראה שזה לא נורא להתשתמש בזה.
    https://stackoverflow.com/a/3536061
    בכל מקרה כך לפי התרגום של גוגל..


  • תכנות

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



  • @חוקר שאלה טובה. התשובה היא ש-express תופסת את השגיאה בשבילך.
    https://expressjs.com/en/guide/error-handling.html



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

    הייתי מוסיף שמבחינתי עצם החיפוש ל"איך יוצאים בפונקציה גם מהפונקציה הקוראת" הוא שלילי. אין. צריך ללמוד איך כותבים תוכנה ואיך מיישמים בדרך שלה את החלום הסופי (ולא את הדרך אליו).


  • תכנות

    @dovid אמר בjs throw false:

    הייתי מוסיף שמבחינתי עצם החיפוש ל"איך יוצאים בפונקציה גם מהפונקציה הקוראת" היא שלילי. אין. צריך ללמוד איך כותבים תוכנה ואיך מיישמים בדרך שלה את החלום הסופי (ולא את הדרך אליו).

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

    let name = read(req, res, 'f-הקלט את שמך', 'name', VOICE);
    if (typeof name !== "string"){return false}
    

    או שאני מצליח בפונקציית הread ליצור מצב שהקוד שלאחר השורה

    let name = read(req, res, 'f-הקלט את שמך', 'name', VOICE);
    

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

    @dovid אמר בjs throw false:

    זה ההשלכה ארוכת הטווח על המתכנת.

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

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

    if (typeof name !== "string"){return false}
    database.insert...
    

    אז פעולת ההכנסה לא תבוצע לפני הזמן, אבל למה ששאר הפעולות כגון חיתוך מחרוזות יבוצע על ערכים לא מאוכלסים ויכולים לגרום שגיאה?
    ולהשים בכל שלב בקוד את ה
    if (typeof name !== "string"){return false}
    אני לא מתחייב שאוכל לעמוד בזה..
    וא"כ אולי זה כן לכתחילה לבצע זאת על ידי throw false ואז הקוד מבוצע שלב שלב.
    שלא תחשוב שאני בא לחלוק על דבריך, אני גם כן מעדיף קוד ושרת בריא ללא סיבוכים מיותרים, אבל פשוט לא הבנתי סוף דעתך באיזה מקומות זה יכול לגרום מיכשול, ומה שזה לא לגיטימי, לא מבהיל אותי כי גם הAPI של ימות המשיח הוא לא הכי לגיטימי...


  • תכנות

    @חוקר אמר בjs throw false:

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

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



  • @יוסף-בן-שמעון אם תצליח למצוא איזה פתרון יצירתי אשמח אם תעדכן אותנו 🙂
    אני חושב על סוג של state machine. משהו בכיוון של switch ארוך ולהגדיר לכל שלב של השיחה state.

    router.get('/test', function (req, res) {
      let state = 'initial';
      let infoNeeded = { message: null, varName: null };
      
      function read (varName, message) {
        if (req.query[varName]) {
          state = `got_${varName}`;
          return req.query[varName];
        } else {
          infoNeeded = { message, varName };
          state = 'needMoreInfo';
        }
      }
    
      function requestInfo (infoNeeded) {
        res.end(`read=${message}=${varName}`);
      }
      
      while (1) {
        switch (state) {
          case 'needMoreInfo':
            return requestInfo(infoNeeded);
          case 'initial':
            var id = read('id', 'הקש תעודת זהות');
            break;
          case 'got_id':
            var name = read('name', 'f-הקלט את שמך');
          case 'got_name':
            var status = read('status', 't-בחר את הסטטוס האישי, לבחור הקש אחד לאברך הקש שתיים לתתלמיד חיידר הקש שלוש')
            break;
          case 'got_status':
            if (status === '1') {
              // ...
            } else if (status === 2) {
              // ...
            }
          default:
            throw new Error('Unknown state!')
        }
      }
    }
    

    אבל ברור שזה צורת חשיבה אחרת מאשר הפתרון של זריקת exception. לקבל קוד קל שעובד בזורם בדיוק בדרך שהראש של @חוקר זורם יהיה מאתגר...
    פתרון נוסף הוא הדרך של @MusiCode דהיינו לעשות שפונקציית ה-read יהיה async ואם המשתנה לא קיים זה יבקש אותו מימות המשיח ויעצור את הפונקציה עד לקריאה הבאה של ימות המשיח. אבל משום מה @חוקר ממאן ללכת בדרך זו. (או משהו דומה - אם כי קצת טריקי - שאני הצעתי פעם בשימוש עם generator-ים)

    @חוקר, חבל שאתה לא הולך בדרך של @MusiCode, אני אוהב אותה...

    בעצם ניתן לקחת את המהלך של state machine שלב קדימה ולחסוך את ה-boilerplate של ה-while וה-switch על ידי כתיבת פונקציה שיקרא אוטומטית לשלב הבא של השיחה על סמך שם המשתנה שהתקבל. והמתכנת יכתוב רק פונקציות עם שמות שנחצבות מתוך שם המשתנה האחרון שהתקבלה בשיחה. נשאיר את זה לשיעורי בית...


  • תכנות

    @yossiz אתה בעצם צודק, אין לי מה לחדש יותר מהפתרונות הידועים, זה נתון לשיקולו של חוקר אם לאמץ אותם או לא



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

    app.get('/xyz', function(req, res){
        var data = {};
    
        if(!read(req, res, data, 'f-הקלט את שמך', 'name', VOICE)) return;
        if(!read(req, res, data, 't-בחר את הסטטוס האישי, לבחור הקש אחד לאברך הקש שתיים לתתלמיד חיידר הקש שלוש', 'status', MENU + '12')) return;
    
        if (data[status] === '1'){
            if(!read(req, res, data, 't-הקלט את שם הישיבה ולסיום הקש סולמית', 'yeshiva', VOICE)) return;
            database.insertSQL({'name' : name,'yeshiva' : yeshiva}, 'bachurim').then(id => {
                say('t-נרשמת בהצלחה המספר האישי שלך הינו.n-' + id);
            })
        }
        ...
    }
    
    function read(req, res, data ...){
         if(data[name] = req.query[name])
               return true;
          else 
               ...
    }
    

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

    הנה דוגמה למשהו גנרי:

    app.get('/xyz', function (req, res) {
        var flow = {
            name: { next: () => ["status"], askUser: `t-בחר את הסטטוס האישי, לבחור הקש אחד לאברך הקש שתיים לתתלמיד חיידר הקש שלוש` /* , ...*/ },
            status: {
                askUser: `t-הקלט את שם הישיבה ולסיום הקש סולמית`, /* , ... ,*/ next: function (val) {
                    if (val == "1") return "yeshiva";
                    if (val == "2") return "isuk";
                    if (val == "3") return "...";
                }
            },
            yeshiva: { next: null, askUser: `t-הקלט את שם הישיבה ולסיום הקש סולמית` },
            isuk: { next: (val) => ({ 1: "kolel", 2: "work" }[val]), askUser: `t-אברך כולל הקש אחד, נהנה מיגיע כפיו הקש שתיים` },
            kolel: { next: null, askUser: `t-הקלט את שם הכולל ולסיום סולמית` },
            work: { next: null, askUser: `t-הקלט את שם מקום העבודה` },
        };
        var data = req.query || {};
    
        if (!proccessStep("name")) //all data ready?
            return false;
    
        //...
        //work with data
        if(data[status] == "1"){
            database.insertSQL({ 'name': name, 'yeshiva': yeshiva }, 'bachurim').then(id => {
                say('t-נרשמת בהצלחה המספר האישי שלך הינו.n-' + id);
            })
        }
        //...
        //...
    
        function proccessStep(key) {
            if (!data[key]) {
                //res.end() ...
                return false;
            }
            var next = flow[key].next(data[key]);
            if (next)
                return proccessStep(next)
            else return true;
        }
    });
    

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

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



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

    @yossiz אמר בjs throw false:

    @חוקר, חבל שאתה לא הולך בדרך של @MusiCode, אני אוהב אותה...

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



  • @yossiz אמר בjs throw false:

    פתרון נוסף הוא הדרך של @MusiCode דהיינו לעשות שפונקציית ה-read יהיה async ואם המשתנה לא קיים זה יבקש אותו מימות המשיח ויעצור את הפונקציה עד לקריאה הבאה של ימות המשי

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



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



  • @yossiz
    😟 איך הספקתי לשכוח מהקטע הזה?
    אז זה אומר שלא לשמור נתונים בזיכרון ,אלא לשמור הכל בדיסק (כמו שחוקר עושה)
    ומרוויחים בעיקר מבנה תקין של הקוד.
    ובכל שלב הוא בודק איזה משתנים הוא קיבל, ואם הוא קיבל כבר 8 משתנים, הוא קופץ קדימה?
    או שלא הבנתי איך הספריה עובדת?


  • תכנות

    @dovid
    ראשית כל אני מעריך מאוד את המאמץ הרב שהשקעת עבורנו!!
    שנית אני יעבור בעיון בל"נ כשיהיה לי יותר ריכוז ואז אשתדל להגיב..



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


התחבר כדי לפרסם תגובה