Promises: then وcatch وfinally وPromise.all
أنشئ Promises وسلسِلها، وتعامل مع الأخطاء في كتل catch، ونفّذ التنظيف في finally، وشغّل عدة Promises بالتوازي باستخدام Promise.all.
Promises: then وcatch وfinally وPromise.all درس مجاني في Frontend Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Frontend Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Frontend Academy 4 دروس في المجموع.
ما هي Promise؟
تمثل Promise قيمة ستصبح متاحة في المستقبل. وهي كائن له إحدى ثلاث حالات: pending (ابتدائية)، أو fulfilled (حُلَّت بقيمة)، أو rejected (فشلت بسبب). بعد استقرارها، تصبح حالة Promise دائمة.
إنشاء Promise
أنشئوا Promise باستخدام الباني new Promise(executor). وتتلقى دالة التنفيذ resolve وreject كدالتي رد اتصال. استدعوا resolve مع قيمة النجاح، أو reject مع خطأ.
const delay = (ms) => new Promise((resolve) => {
setTimeout(resolve, ms);
});
const fetchData = (url) => new Promise((resolve, reject) => {
fetch(url)
.then(res => res.json())
.then(resolve)
.catch(reject);
});.then() — معالجة النجاح
يسجّل promise.then(onFulfilled) دالة رد اتصال تُنفَّذ عند اكتمال Promise. وتتلقى القيمة الناتجة. يعيد .then() Promise جديدة، مما يتيح تسلسل الاستدعاءات.
fetch('/api/users')
.then(response => response.json())
.then(users => {
console.log('Users:', users);
return users.length;
})
.then(count => console.log('Count:', count));.catch() — معالجة الأخطاء
تعالج promise.catch(onRejected) حالات الرفض. وعند وضعها في نهاية سلسلة، تلتقط أي خطأ ناتج عن أي خطوة سابقة فيها.
fetch('/api/data')
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then(data => processData(data))
.catch(err => {
console.error('Failed:', err.message);
showErrorToUser();
});.finally() — التنفيذ دائمًا
تُنفَّذ promise.finally(onFinally) سواء اكتملت Promise أو رُفضت. وهي مثالية للتنظيف، مثل إخفاء مؤشر التحميل أو تحرير قفل أو تسجيل بيانات التحليلات.
showSpinner();
fetch('/api/data')
.then(res => res.json())
.then(render)
.catch(handleError)
.finally(() => hideSpinner()); // always runsتسلسل Promises — إعادة القيم
أعيدوا قيمة من .then()، فتصبح القيمة الناتجة لـ .then() التالية. وأعيدوا Promise جديدة لتسلسل العمليات غير المتزامنة.
getUser(id)
.then(user => getOrders(user.id)) // return Promise
.then(orders => orders[0]) // return value
.then(order => console.log(order)); // receive orderPromise.all() — التشغيل بالتوازي
تنتظر Promise.all([p1, p2, p3]) اكتمال جميع Promises، ثم تعيد مصفوفة من النتائج بالترتيب نفسه. إذا رُفضت أي Promise، تُرفض العملية بأكملها فورًا.
const [user, posts, comments] = await Promise.all([
fetch('/api/user/1').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/comments').then(r => r.json()),
]);
// All three run in parallel — much faster than sequentialPromise.allSettled() — عدم الفشل السريع
تنتظر Promise.allSettled() استقرار جميع Promises (حلّها أو رفضها)، ثم تعيد مصفوفة من كائنات النتائج التي تحتوي على {status, value} أو {status, reason}. وتفيد عندما لا تريدون أن يؤدي فشل واحد إلى إلغاء جميع النتائج.
const results = await Promise.allSettled([p1, p2, p3]);
results.forEach(result => {
if (result.status === 'fulfilled') use(result.value);
else logError(result.reason);
});Promise.race() وPromise.any()
تحلّ Promise.race() أو ترفضها Promise التي تستقر أولًا. وتحلّ Promise.any() مع أول Promise مكتملة (وتتجاهل حالات الرفض، ولا تُرفض إلا إذا رُفضت جميع Promises). وتفيد في حالات المهلة الزمنية والتكرار الاحتياطي.
// Timeout pattern:
const withTimeout = (promise, ms) => Promise.race([
promise,
new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), ms))
]);إنشاء Promises مستقرة مسبقًا
تنشئ Promise.resolve(value) Promise مكتملة مسبقًا بالقيمة value. وتنشئ Promise.reject(error) Promise مرفوضة مسبقًا. وتفيد هذه الدوال في الاختبار ودوال التكييف.
const p = Promise.resolve(42);
p.then(v => console.log(v)); // 42أحداث الرفض غير المعالج
إذا رُفضت Promise من دون .catch()، أصبحت حالة رفض غير معالج. تصدر المتصفحات الحديثة وNode.js تحذيرات في هذه الحالة. أضيفوا دائمًا .catch() أو استخدموا try/catch مع async/await.
window.addEventListener('unhandledrejection', event => {
console.error('Unhandled rejection:', event.reason);
event.preventDefault();
});اختبار سريع
ما الطريقة الساكنة التي تشغّل عدة Promises بالتوازي وتُحلّ بمصفوفة تحتوي على جميع النتائج؟
مراجعة: Promises
استخدموا .then() للنجاح، و.catch() للأخطاء، و.finally() للتنظيف. تمرر السلاسل القيم من خطوة إلى أخرى. تنفذ Promise.all() العمليات بالتوازي. وتتحمل Promise.allSettled() الفشل الجزئي. استخدموا Promise.race() للحصول على النتيجة الأسرع. عالجوا حالات الرفض دائمًا. تستخدم الشفرة الحديثة async/await بوصفها صياغة نحوية مختصرة فوق Promises.
الأسئلة الشائعة
هل درس «Promises: then وcatch وfinally وPromise.all» مجاني؟
نعم — نص درس «Promises: then وcatch وfinally وPromise.all» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Frontend Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Frontend Academy 4 دروس في المجموع.
ماذا ستتعلم في «Promises: then وcatch وfinally وPromise.all»؟
أنشئ Promises وسلسِلها، وتعامل مع الأخطاء في كتل catch، ونفّذ التنظيف في finally، وشغّل عدة Promises بالتوازي باستخدام Promise.all. تتمرن على Frontend Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Frontend Academy؟
لا تُشترط خبرة سابقة. Frontend Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «Promises: then وcatch وfinally وPromise.all»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Frontend Academy هذا؟
نعم. كل درس في Frontend Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- حلقة الأحداث: مكدس الاستدعاءات وطابور المهام والمهام المصغّرة
- دوال الاستدعاء وجحيم الاستدعاءات
- Promises: then وcatch وfinally وPromise.all
- async/await ومعالجة الأخطاء