• בלוג
  • שינוי ההתנהגות המובנית ב JavaScript

שינוי ההתנהגות המובנית ב JavaScript

14/04/2026

גם גבור קוס ראה את הקוד הזה והרגיש בחילה:

const todoResponse = await client.get('/api/todos/1');
const todo = await todoResponse.json();

הבעיה? הוא לא צריך את todoResponse והגדיר אותו רק בשביל להפעיל עליו .json. יש כמה דרכים טבעיות ב JavaScript לוותר עליו, אבל אף אחת מהן לא עושה חשק. הראשונה היא להשתמש בשני await באותה שורה:

const todo = await (await client.get('/api/todos/1')).json();

ודרך שניה עם then:

const todo = await client.get('/api/todos/1').then(r => r.json());

החלום של גבור היה לכתוב קוד שנראה כך:

const todo = await client.get('/api/todos/1').json()

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

1. מה אנחנו מפסידים כשאנחנו משנים התנהגות

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

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

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

את גרסת שני ה await-ים אני לא אוהב, היא נראית לא טבעית, אבל לפחות אני מבין אותה במבט ראשון.

גרסת ה await הבודד היא הכי מבלבלת. בתור מפתח וותיק אני קורא את זה ולא מבין איפה ה then של ה get, ולמה מתיחסים ל Promise כמו לתוצאה שלה. אם הייתי מפתח חדש שלא מספיק מכיר JavaScript הייתי עלול לחשוב שאפשר להתנהג בצורה דומה גם עם פונקציות אחרות של Promises או עם Promises אחרים, וזו כמובן היתה טעות.

הבלבול רק מחריף כשאנחנו מנסים להשתמש בגרסה זו בהקשרים אחרים, לדוגמה:

const todoRequest = await client.get('/api/todos/1');
const todo = todoRequest.json();

במקרה הזה השורה השניה תחזיר Promise כי ה await שלה "נשכח" בשורה הראשונה. הדרך הנכונה לשבור את הקוד לשתי שורות היא דווקא לשים את ה await בשורה השניה ולקרוא ל json ישירות על ה Promise:

const todoRequestPromise = client.get('/api/todos/1');
const todo = await todoRequestPromise.json();

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

במקרה של fetch הרבה יותר קל ונכון להשתמש בכתיב ה then כדי לשרשר Promises וכך נלמד מבנה שיעזור לנו גם באתגרים דומים בעתיד. אם מתעקשים אפשר לכתוב פונקציה בשם אחר, למשל getJson שמפעילה את ה then ומחזירה Promise ל json.