@dovid אמר בפרומיסים לוקחים זמן?:
הסר דאגה מליבך כשאתה עושה פרומייז אבל אל תמתין אף פעם אם אין צורך (לא בגלל אטיות/מהירות, אלא כדי להיפטר מהלקוח שמחכה לתשובה כמה שיותר מהר, זה טוב לו ואפילו טוב לשרת).
חידה לי דבריך. לא להמתין - לא בגלל מהירות, אלא כדי לתת ללקוח תשובה כמה שיותר מהר??
שורה תחתונה אחרי דבריך ודברי @רפאל המנגנון של מאחורי הקלעים של הפרומיסים אכן יותר מובן, ובכל זאת אני לא בטוח שיש תשובה לשאלתי.
בהינתן פונקציה שמבצעת לוגיקה מסוימת, במצב מסוים מספיק לוגיקה טהורה, ובתנאי מסוים יש צורך להעזר במידע חיצוני - קראיה מקובץ לצורך הענין. הלוגיקה חייבת להעשות באותו סדר, ולכן צריך להמתין לקריאת הקובץ לפני שממשיכים, וממילא להמתין לתשובת כל הפונקציה שהופכת בעצמה לפרומיס.
יוצא שהפכתי את הפונקציה לפרומיס, למרות שלא בכל ריצה שלה אני באמת צריך אותה כפרומיס. אז כשצריך (נדרש נתון מקובץ) - צריך, גם אם יש לזה מחיר של זמן (בכל מקרה הIO עצמו לוקח זמן ויש לזה יותר משמעות), אבל כשלא צריך - השימוש בפרומיס מיותר.
אני יכול לעשות פקטוריזציה של הקוד באופן שיבדוק מראש האם צריך נתון חיצוני ולפי זה ידע האם לקרוא לפונקציה של פרומיס או לפונקציה רגילה. אבל במקרה שלי מדובר בפקטוריזציה מסובכת מאוד עם מחירים משמעותיים אחרים. ולכן אני מנסה להבין את ה"עלות" של השימוש המיותר בפרומיס. ובמחילה, טרם הצלחתי להבין. מחד אתם אומרים שלא אמורה להיות לפרומיס משמעות של זמן יותר ממה שהיה לוקח ממילא. מאידך אתם מסבירים שמשימה שבתוך פרומיס מקבלת עדיפות נמוכה, ואתה עצמך כותב לא להמתין אם אין צורך.
נדמה לי שיש פה אי הבנה מסוימת על המקרה המדויק שאליו אני מתייחס, אז אנסה לכתוב פה קוד שלם שממחיש את השאלה/
בדוגמה הבאה, הלקוח שולח בקשה לשרת, שקורא לפונקציה שמחזירה נתונים ושולחת ללקוח.
במידה ובנתונים שהלקוח שלח נכללת ההרשאה שלו (המחשה בלבד.....) הלוגיקה מתבצעת בלי להעזר במקור חיצוני (היא מחזירה סטרינג מוכן) ולכן השימוש בפרומיס (הגדרת הפונקציה כasync
) מיותר, וכך גם ההמתנה לו.
async function getData(userData) {
if (userData.type == undefined) {
userData.type = await readFile(`path/to/${userData.id}`);
}
return userData.type == "manager" ? "secreet data" : "free data";
}
router.get("/", async (req, res, next) => {
const userData = req.body.userData;
let result = await getData(userData);
res.send(result);
});
לעומת זאת, יכולתי לכתוב את הקוד בצורה כזו:
async function getData(userData) {
return userData.type == "manager" ? "secreet data" : "free data";
}
async function getUnexpectedData(userData) {
userData.type = await readFile(`path/to/${userData.id}`);
return userType == "manager" ? "secreet data" : "free data";
}
router.get("/", async (req, res, next) => {
const userData = req.body.userData;
let result;
if (userData.type == undefined) {
result = await getUnexpectedData(userData);
} else {
result = getData(userData);
}
res.send(result);
});
בצורה האחרונה, איני משתמש בפרומיס אלא אם אני באמת צריך אותו. האם הצורה הזו יעילה יותר מהצורה הראשונה? האם הרצת הקוד (בהנחה שהuserData.type כן הגיע מהלקוח כך שהפרומיס מיותר) תסתיים מהר יותר, וממילא התשובה תישלח ללקוח מהר יותר?