תפוס שגיאות ב-Promise.all

חלופה בטוחה ל-Promise.all של Javascript

ממתין לכל ההבטחות כולל שגיאות

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

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

Promise.allSettled ממתין לכל תוצאות הסנכרון

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

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

מתן מערך ריק

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

/**
 * A simple dummy function that
 * fetches data from multiple
 * endpoints related to a user.
 */
async function fetchUserData(id){
  // A simple array of promises.
  // The first two parameters are
  // mock calls from down below.
  const promises = [
    fetchUserHistory(id),
    fetchUserProfile(id),
    // For testing only, let's throw.
    Promise.reject(new Error('an error'))
];
  
  const values = await Promise.allSettled(promises);
  // values === [
  //    { status: "fulfilled", value: [1, 2, 3] },
  //    { status: "fulfilled", value: {name:"dummy"} },
  //    { status: "rejected", reason: {}
  // ]
}

// The following functions are just mocks
// and should help improve readability
// of the example at the top.

async function fetchUserHistory(id){
  return Promise.resolve([1,2,3]);
}

async function fetchUserProfile(id){
  return Promise.resolve({ name: "dummy" });
}

כפי שאתה יכול לראות, Promise.allSettled היא תוספת נחמדה מאוד ל-Promise.all ומאפשרת לך להמתין לכל התוצאות, ללא תלות בתוצאות שלהן. אני לא חושב שה-API הזה יתאים לכל מקרה שימוש, אבל זה בטוח חוסך ממך לעטוף שיחות אסינכרון ב-Try-catch-block תקורה.