المستوى المطلوب: متوسط
هذا المقال يفترض إنك مرتاح مع async/await و Promises الأساسية. لو لسه بتبدأ، ابدأ بمفهوم الـ Promise نفسه أولاً ثم ارجع هنا.
Promise.all vs Promise.allSettled في JavaScript: ليه طلب واحد بيكسرلك 9 طلبات شغّالة
لو dashboard بتاعك بيجيب بيانات 10 خدمات في وقت واحد، وأول ما خدمة واحدة بتفشل بتلاقي الـ 9 الباقيين راحوا في الهوا، المشكلة مش في الـ network. المشكلة إنك بتستخدم Promise.all في موقف كان لازم يبقى فيه Promise.allSettled. الفرق بين الاتنين سطر كود واحد، لكن أثره على نسبة فشل الواجهة هائل.
المشكلة باختصار: كل الطلبات بتشتغل، طلب واحد بيكسر الباقي
تخيّل إنك بعت 10 سعاة بريد في نفس اللحظة، كل واحد بطرد لعنوان مختلف. لو ساعي واحد ضاع في الزحمة، إنت لسه عايز تستلم الـ 9 الطرود الباقية اللي وصلت بسلام، صح؟ ده اللي بيعمله Promise.allSettled. Promise.all بالعكس تماماً: لو ساعي واحد ضاع، الـ runtime بيعتبر العملية كلها فشلت ويرمي الـ 9 طرود الباقية في الزبالة، ويرجّعلك exception بسبب الساعي الواحد اللي ضاع.
تقنياً، Promise.all([p1, p2, ..., pN]) بيرجّع Promise جديد. لو أي promise جوّاه عمل reject، الـ Promise النهائي بيعمل reject فوراً بنفس السبب — وأي قيم نجحت بتتساب من غير ما تتعرض للكود اللي طلبها. Promise.allSettled بيستنى كل الـ promises تخلص (سواء fulfilled أو rejected) ويرجّع array من objects شكلها {status: 'fulfilled', value} أو {status: 'rejected', reason}. مفيش طلب بيضيع، وإنت اللي بتقرر تعمل إيه مع كل واحد.
سيناريو إنتاج: dashboard بيجيب 10 خدمات
عندي تطبيق dashboard لشركة logistics بيجيب بيانات من 10 microservices: shipments، invoices، users، notifications، analytics، tracking، billing، support، partners، alerts. كل خدمة بتاخد بين 80ms و 320ms. الكود الأصلي كان كده:
async function loadDashboard(userId) {
const [shipments, invoices, users, notifications, analytics,
tracking, billing, support, partners, alerts] = await Promise.all([
fetch(`/api/shipments?u=${userId}`).then(r => r.json()),
fetch(`/api/invoices?u=${userId}`).then(r => r.json()),
fetch(`/api/users/${userId}`).then(r => r.json()),
fetch(`/api/notifications?u=${userId}`).then(r => r.json()),
fetch(`/api/analytics?u=${userId}`).then(r => r.json()),
fetch(`/api/tracking?u=${userId}`).then(r => r.json()),
fetch(`/api/billing?u=${userId}`).then(r => r.json()),
fetch(`/api/support?u=${userId}`).then(r => r.json()),
fetch(`/api/partners?u=${userId}`).then(r => r.json()),
fetch(`/api/alerts?u=${userId}`).then(r => r.json())
]);
return { shipments, invoices, users, notifications, analytics,
tracking, billing, support, partners, alerts };
}