DanLevy.net

תפסיקו לנסות להפוך את async/await לדבר

הבטחות זה כל כך טרנדי עכשיו

Hero image for תפסיקו לנסות להפוך את async/await לדבר

מאז ראשית הימים, מפתחים ניהלו מלחמות מטופשות רבות. מהוויכוח הקלאסי “Tab לעומת Space” ועד לוויכוח הנצחי “Mac לעומת PC”, אנחנו טובים בלמצוא ויכוחים מסיחי דעת.


תשובות: לינוקס ו-Space.

הקרב…?

Promises לעומת Async/Await!

רגע, זה קרב? זה חייב להיות קרב, נכון? נראה שכבר לא מדברים על callbacks?

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

יש הרבה אנשים משפיעים שמקדמים את התפיסה המוטעית ש-async/await הוא התחליף שכולם חיכו לו עבור Promises.

רמז: לא, לא, ואפילו לא קצת.

תוספת אחרונה ל-VS Code מקדמת את ההטיה הזו. כפי ש-@umaar צייץ:

Visual Studio Code יכול כעת להמיר את השרשראות הארוכות שלך של Promise.then() ל-async/await! 🎊 עובד מצוין גם בקבצי JavaScript וגם ב-TypeScript. .catch() מומר גם בצורה נכונה ל-try/catch ✅ pic.x.com/xb39Lsp84V

— Umar Hansa (@umaar) 28 בספטמבר 2018

אם אתה שונא Promises, ורוצה את תכונת הרפקטורינג הזו, אני לא מאשים אותך.


אני מזדהה. אני מבין.


הייתי שם. 🤗


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

יש 2 תחומים שאני ממליץ להתמקד בהם תחילה כדי לקדם את טכניקת ה-Promise שלך.

  1. פונקציות בעלות שם (ללא אנונימיות)
  2. פונקציות בעלות מטרה יחידה

#1: פונקציות בעלות שם!

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

בואו נסתכל על דוגמה נפוצה:

ביצוע בקשת HTTP GET באמצעות fetch:

אנטי-דפוס

// ❌ שימוש בפונקציות אנונימיות מוטבעות 💩
fetch(url)
.then(response => response.status < 400
? response
: Promise.reject(new Error('Request Failed: ' + response.ststus)))
.then(response => response.text())

פתרון: מתודות בעלות שם

// ✅ בהירות צצה: פונקציות בעלות שם
fetch(url)
.then(checkResponse)
.then(getText)
// פונקציות לשימוש חוזר ומטרה כללית
function checkResponse(response) {
return response.status < 400
? response
: Promise.reject(new Error('Request Failed: ' + response.ststus))
}
function getText(response) {
return response.text()
}

היתרונות של גישה זו הופכים ברורים יותר ככל שהקוד הופך יבש יותר (DRY).

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

#2: מטרה יחידה (פונקציות)

זה נשמע מדויק בצורה מטעה: מטרה יחידה.

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

מעניין, רוב המפתחים מדווחים שהם די טובים בלהקנות מטרה יחידה לקוד שלהם. לא בלי קשר: הם מדווחים שהם גם נהגים מעולים!

בואו נסתכל על דוגמה שג’ייק ארצ’יבלד (המוכשר להפליא) מציג במאמרו על async/await באתר Google Developers (הערה: 2024, הקישור הוסר).

// source: https://developers.google.com/web/fundamentals/primers/async-functions
function logInOrder(urls) {
// fetch all the URLs
const textPromises = urls.map(url => {
return fetch(url).then(response => response.text());
});
// log them in order
textPromises.reduce((chain, textPromise) => {
return chain.then(() => textPromise)
.then(text => console.log(text));
}, Promise.resolve());
}

מטרה יחידה?

הייתי אומר שלא. מה logInOrder עושה?

  1. עובר בלולאה על רשימת urls
  2. מפעיל עליהם בקשת HTTP מוטבעת:
    1. fetch של HTTP
    2. מחזיר את גוף התגובה כטקסט
  3. מצרף .then(text => console.log(text)) אחרי כל promise ב-textPromise
    1. מדפיס תוצאות בסדרתיות

יש 5 מתודות אנונימיות המוגדרות בפונקציה היחידה הזו. כפי שג’ייק עצמו מציין, ה-.reduce מסובך מדי. אין טעם לכתוב מנגנונים מורכבים בעבודת יד בכל הקוד שלך. במילים אחרות, אנחנו לא כותבים קוד ליצירת DOM עם אינסוף document.createElement(), element.setAttribute() וכו’. במקום זאת, אנו בוחרים בכלי הטוב ביותר מתוך אפשרויות רבות: פונקציות עזר/שירות, ספריות או פריימוורקים.

פתרון: פונקציות בעלות מטרה יחידה

התחל בחילוץ מתודות

VS Code מחלץ מתודות אסינכרוניות מקוד Promise

המשך בהחלפת ה-.reduce() ו-logPromise() ב-Promise.all ו-..map()

שרשרת Promise שעברה רפקטורינג באמצעות Promise all ו-map לשיפור קריאות

סיכום

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

עזרו להפיץ את #PromiseTruth ושתפו את המאמר. ❤️

קרדיט: matt-nelson-414464-unsplash.webp

קריאה נוספת