أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول
البرمجة بالعربي

Promise.allSettled بالعربي: خلّي الصفحة تكمل رغم فشل API

📅 ٢٥ أبريل ٢٠٢٦⏱ 4 دقائق قراءة
Promise.allSettled بالعربي: خلّي الصفحة تكمل رغم فشل API

Promise.allSettled بالعربي: خلّي الصفحة تكمل رغم فشل API

لو صفحة المنتج عندك بتكسر كلها عشان API واحد وقع، المقال ده هيخليك تعرض البيانات المتاحة وتفصل الفشل بدل ما تعاقب المستخدم على خدمة واحدة.

مستوى القارئ: متوسط

المشكلة باختصار

افترض إن صفحة منتج بتجيب السعر، التقييمات، والمخزون من 3 endpoints مختلفة. السعر بيرجع في 120ms، المخزون في 160ms، لكن reviews API بيعمل timeout بعد 900ms. مع Promise.all، فشل reviews بيرفض العملية كلها. النتيجة: صفحة فاضية أو error عام رغم إن عندك بيانات كفاية تعرضها.

الطريقة دي بتفشل في الواجهات اللي تقبل partial data. بدل ما توقف الصفحة كلها، الأفضل تسأل كل promise: نجحت ولا فشلت؟ هنا يظهر دور Promise.allSettled.

مخطط يوضح صفحة منتج تجمع نتائج ثلاث APIs مع فشل reviews واستخدام fallback عبر Promise.allSettled

الفكرة بمثال واضح

ركز في المثال ده. عندك فريق بيجهز طلب: شخص جاب السعر، شخص جاب حالة المخزون، وشخص فشل يجيب التقييمات. هل تلغي الطلب كله؟ غالبًا لا. تعرض السعر والمخزون، وتكتب مكان التقييمات: غير متاحة مؤقتًا.

بالظبط ده اللي بيعمله Promise.allSettled. هو لا يرمي exception لمجرد إن promise واحدة فشلت. هو يرجع array فيها نتيجة كل promise: fulfilled ومعاها value، أو rejected ومعاها reason.

مثال JavaScript قابل للنسخ

الافتراض إن عندك واجهة متجر، وكل endpoint مستقل. لو التقييمات فشلت، الصفحة تفضل قابلة للاستخدام.

JavaScript
async function loadProductPage(productId) {
  const requests = [
    fetch(`/api/products/${productId}/price`).then(r => r.json()),
    fetch(`/api/products/${productId}/reviews`).then(r => r.json()),
    fetch(`/api/products/${productId}/stock`).then(r => r.json()),
  ];

  const [priceResult, reviewsResult, stockResult] = await Promise.allSettled(requests);

  return {
    price: priceResult.status === "fulfilled" ? priceResult.value : null,
    reviews: reviewsResult.status === "fulfilled" ? reviewsResult.value : [],
    stock: stockResult.status === "fulfilled" ? stockResult.value : { available: false },
    warnings: [priceResult, reviewsResult, stockResult]
      .map((result, index) => ({ result, index }))
      .filter(item => item.result.status === "rejected")
      .map(item => `request_${item.index}_failed`),
  };
}

في سيناريو واقعي، صفحة فيها 3 أقسام. مع Promise.all وفشل request واحد، المعروض يساوي 0 أقسام. مع Promise.allSettled، ممكن تعرض 2 من 3 أقسام. الرقم هنا بسيط لكنه مهم: بدل 0% من الصفحة، تعرض حوالي 66% من المحتوى المفيد.

رسم أعمدة يقارن بين Promise.all وPromise.allSettled عند فشل API واحد في صفحة تعتمد على ثلاث APIs

إمتى تستخدم Promise.all وإمتى allSettled

استخدم Promise.all لما كل النتائج تعتمد على بعض. مثال: لازم تجيب user session، بعدها permissions، بعدها invoice. لو خطوة فشلت، الباقي ملوش معنى.

استخدم Promise.allSettled لما النتائج مستقلة. مثال: dashboard فيه revenue، alerts، وlatest comments. فشل comments لا يمنع عرض revenue. الـ trade-off هنا واضح: بتكسب واجهة أكثر تحملًا للفشل، لكن بتخسر بساطة الكود. لازم تعمل handling لكل حالة بدل catch واحد عام.

كمان خليك واعي إن allSettled لا يوقف الطلبات البطيئة. هو ينتظر كل promises تنتهي، سواء نجاح أو فشل. لو عندك timeout مهم، استخدم AbortController أو timeout wrapper بجانبها.

قياس عملي قبل وبعد

لو عندك 50K زيارة يوميًا وصفحة المنتج تعتمد على 3 APIs، ومعدل فشل reviews API هو 2%، فأنت ممكن تكسر حوالي 1000 مشاهدة يوميًا بدون داعي. بعد التحويل إلى allSettled، نفس الـ 1000 مشاهدة تقدر تعرض السعر والمخزون مع رسالة fallback للتقييمات.

المكسب: تقليل صفحات الخطأ الظاهرة للمستخدم. الخسارة: محتاج تصميم fallback واضح، logging جيد، وتنبيه لما failure rate يزيد. لو تجاهلت المراقبة، ممكن تخفي مشكلة حقيقية تحت واجهة تبدو شغالة.

متى لا تستخدم هذه الطريقة

لا تستخدم Promise.allSettled لو فشل جزء واحد يجعل النتيجة كلها غير آمنة. صفحة دفع لا ينفع تعرضها جزئيًا لو فشل حساب الضرائب أو تحقق المخزون النهائي. في الحالات دي، الفشل الصريح أفضل من قرار ناقص.

ولا تستخدمها كبديل عن retry أو circuit breaker. هي طريقة لتجميع النتائج، مش علاج لتعطل الخدمة نفسها.

مصادر اعتمدت عليها

  • MDN: توثيق Promise.allSettled() يوضح شكل النتائج وحالات fulfilled وrejected.
  • MDN: توثيق Promise.all() يوضح سلوك الرفض السريع عند فشل أي promise.
  • MDN: توثيق AbortController مفيد لو عايز تضيف timeout أو إلغاء للطلبات البطيئة.

الخطوة التالية

افتح أول صفحة عندك بتعمل 3 طلبات مستقلة، واستبدل Promise.all بـ Promise.allSettled في تجربة صغيرة. لو المستخدم يقدر يستفيد من نتيجتين رغم فشل الثالثة، يبقى التغيير يستحق الدخول في production بعد إضافة logging.

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة