اكتشف الأخطاء في Promise.all

بديل آمن لـ Javascript's Promise.all

انتظار كل الوعود بما فيها من أخطاء

إذا كنت مطورًا لجافا سكريبت ، فمن المرجح أنك استخدمت معيار Object Promise و API Promise.all الخاص به ، والذي ينتظر حتى يتم حل جميع الوعود المقدمة في المصفوفة. هذه طريقة رائعة للغاية لانتظار العديد من النتائج غير المتزامنة قبل متابعة منطق عملك.

لكن واجهة برمجة التطبيقات هذه لا تتعامل مع الأخطاء. عندما يحدث خطأ واحد على الأقل في مجموعة الوعود ، تتوقف الوظيفة على الفور ولا يُنتظر المزيد من النتائج.

Promise.allSettled ينتظر جميع النتائج غير المتزامنة

لحسن الحظ ، هناك واجهة برمجة تطبيقات ثانية تسمى 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 ويسمح لك بانتظار جميع النتائج بغض النظر عن نتائجها. لا أعتقد أن واجهة برمجة التطبيقات هذه ستلائم كل حالة استخدام ، لكنها بالتأكيد توفر عليك من التفاف المكالمات غير المتزامنة في كتلة try-catch-catch العلوية.