فئة الوعد في JavaScript

فئة الوعد في JavaScript

في هذه المقالة، نشرح فئة الوعد في JavaScript۔

YouTube Video

Promise

فئة Promise هي فئة لمعالجة العمليات غير المتزامنة۔ تتعامل مع النتائج إذا نجحت العملية أو معالجة الأخطاء إذا فشلت۔ تقليديًا، كانت تُستخدم دوال رد الاتصال عندما تحتاج إلى انتظار انتهاء العملية غير المتزامنة، ولكن Promise يجعل هذا أكثر وضوحًا وقوة۔

1const promise = new Promise((resolve, reject) => {
2    setTimeout(() => resolve("Done!"), 1000);
3});
4
5// Displays "Done!" after 1 second
6promise.then(result => console.log(result));
  • هذا الكود هو مثال لعملية غير متزامنة تعرض "تم!" بعد ثانية واحدة۔
    • أولاً، يتم إنشاء كائن Promise جديد باستخدام new Promise۔ المُعامل هو دالة تأخذ ردّي اتصال: resolve للنجاح وreject للفشل۔
    • يُستخدم setTimeout لاستدعاء resolve() بعد ثانية واحدة۔
    • دالة then() في كائن الـ promise تنتظر اكتمال التنفيذ وتعرض النتيجة۔

البنية الأساسية

الـ Promise هو كائن يؤدي في النهاية إما إلى نجاح أو فشل۔

 1const promise = new Promise((resolve, reject) => {
 2    // Asynchronous operation
 3    // Flag indicating whether the operation was successful
 4    const success = true;
 5
 6    if (success) {
 7        resolve('Operation successful!');
 8    } else {
 9        reject('An error occurred');
10    }
11});
  • في حالة النجاح، يتم استدعاء resolve()۔
  • في حالة الفشل، يتم استدعاء reject()۔

كائن Promise له ثلاث حالات۔

1promise
2    .then((result) => {
3        console.log(result);
4    })
5    .catch((error) => {
6        console.error(error);
7    })
  • قيد الانتظار
    • العملية غير المتزامنة لم تكتمل بعد۔
  • محَقَّق
    • نجحت العملية غير المتزامنة وتمت إعادة النتيجة بواسطة resolve()۔ يتم استقبال النتيجة باستخدام دالة then()۔
  • مرفوض
    • فشلت العملية غير المتزامنة وحدث خطأ عبر reject()۔ يتم استقبال الخطأ باستخدام دالة catch()۔

طرق then() وcatch()

باستخدام Promise، يمكنك تحديد ماذا تفعل عند اكتمال العملية غير المتزامنة۔ لهذا، تستخدم طرق then() وcatch()۔

then()

1const promise = new Promise((resolve, reject) => {
2    resolve('Operation successful!');
3});
4
5promise.then((result) => {
6    console.log(result);  // "Operation successful!"
7});
  • طريقة then() تحدد وظيفة يتم استدعاؤها عند نجاح الـ Promise۔

catch()

1const promise = new Promise((resolve, reject) => {
2    reject('An error occurred');
3});
4
5promise.catch((error) => {
6    console.error(error);  // "An error occurred"
7});
  • طريقة catch() تحدد وظيفة يتم استدعاؤها عند فشل الـ Promise۔

طريقة finally()

 1const promise = new Promise((resolve, reject) => {
 2    resolve('Operation successful!');
 3});
 4
 5promise
 6    .then((result) => {
 7        console.log(result);
 8    })
 9    .catch((error) => {
10        console.error(error);
11    })
12    .finally(() => {
13        console.log('The operation has completed');
14    });
  • طريقة finally() تحدد كودًا يتم تنفيذه في النهاية بغض النظر عما إذا كانت الـ Promise قد نجحت أم فشلت۔

سلسلة then()

then() يُرجِع كائن Promise جديد، لذلك يمكنك سلسلة دالة then() التالية.۔

 1const promise = new Promise((resolve, reject) => {
 2    setTimeout(() => {
 3        resolve(1);
 4    }, 1000);
 5});
 6
 7promise
 8    .then(result => {
 9        console.log(result); // 1
10        return result + 1;
11    })
12    .then(result => {
13        console.log(result); // 2
14        return result + 1;
15    })
16    .then(result => {
17        console.log(result); // 3
18    })
19    .catch(error => {
20        console.error(error.message); // Something went wrong
21    });
  • في هذا الكود، تقوم دالة resolve() الأولى بتمرير القيمة ١، وكل قيمة تُرجعها دالة then تمرر إلى دالة then التالية.۔
  • باستخدام دالة catch()، يمكنك معالجة أي خطأ يحدث في السلسلة في مكان واحد.۔

مثال عملي

على سبيل المثال، يتم استخدام Promises غالبًا لجلب البيانات من الخادم۔ دعونا نلقي نظرة على مثال باستخدام واجهة برمجة التطبيقات fetch()۔

 1fetch('https://codesparklab.com/json/example.json')
 2    .then(response => {
 3        if (!response.ok) {
 4            throw new Error('Network error');
 5        }
 6        return response.json();
 7    })
 8    .then(data => {
 9        console.log(data);
10    })
11    .catch(error => {
12        console.error('Error:', error);
13    });
  • في هذا الكود، نظرًا لأن fetch() تُرجع Promise، يتم استخدام then() لمعالجة البيانات بعد تلقي الاستجابة من الخادم۔ يتم التعامل مع الأخطاء باستخدام catch()۔

التعامل مع وعود متعددة

Promise.all()

لتنفيذ وعود متعددة في وقت واحد والمتابعة فقط إذا نجحت كلها، استخدم Promise.all()۔

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.resolve(2);
 3const promise3 = Promise.resolve(3);
 4
 5Promise.all([promise1, promise2, promise3])
 6    .then((results) => {
 7        console.log(results);  // [1, 2, 3]
 8    })
 9    .catch((error) => {
10        console.error('Error :', error);
11    });
  • يُستدعى then() فقط إذا نجحت جميع الوعود۔ يُستدعى catch() إذا فشل أحدها ولو واحد۔

Promise.allSettled()

إذا كنت ترغب في تشغيل عدة كائنات Promise في نفس الوقت والحصول على جميع النتائج بغض النظر عن النجاح أو الفشل، استخدم Promise.allSettled()

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.reject("Failed");
 3const promise3 = Promise.resolve(3);
 4
 5Promise.allSettled([promise1, promise2, promise3])
 6    .then((results) => {
 7        results.forEach(result => console.log(result));
 8        // [
 9        //   { status: 'fulfilled', value: 1 },
10        //   { status: 'rejected', reason: 'Failed' },
11        //   { status: 'fulfilled', value: 3 }
12        // ]
13    });
  • يتم استدعاء دالة then() بمجرد أن تنتهي جميع كائنات Promise (سواء تم تنفيذها بنجاح أو تم رفضها).۔ يشمل كل ناتج خاصية status (إما 'fulfilled' أو 'rejected').۔ حتى إذا فشل بعضها، فإن ذلك لا يؤثر على العمليات الأخرى.۔

Promise.race()

Promise.race() تُعيد نتيجة الـ Promise التي تُحسم أولاً سواء كانت مُحققة أو مرفوضة۔

1const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'First'));
2const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'Second'));
3
4Promise.race([promise1, promise2]).then((result) => {
5    console.log(result);  // "First"
6});
  • كما في هذا المثال، يتم إرجاع نتيجة أول Promise مكتمل۔

العلاقة مع async/await

استخدام بناء الجملة async/await يسمح لك بكتابة الوعود بطريقة أكثر وضوحًا۔ دالة async تُرجع دائمًا Promise، وawait تنتظر انتهاء Promise۔

 1async function fetchData() {
 2    try {
 3        const response = await fetch('https://codesparklab.com/json/example.json');
 4        const data = await response.json();
 5        console.log(data);
 6    } catch (error) {
 7        console.error('Error :', error);
 8    }
 9}
10
11fetchData();

باستخدام async/await بهذه الطريقة، يمكن كتابة العمليات غير المتزامنة مثل الكود المتزامن، مما يجعلها أسهل قراءة۔

الملخص

  • Promise هو كائن لمعالجة نجاح أو فشل العمليات غير المتزامنة۔
  • تعامل مع العمليات الناجحة باستخدام then() والأخطاء باستخدام catch()۔
  • finally() يُعرّف تعليمات برمجية تُنفذ في النهاية بغض النظر عن النجاح أو الفشل۔
  • يمكنك التعامل مع وعود متعددة معًا باستخدام Promise.all() أو Promise.race()۔
  • async/await هو بناء جملة لكتابة الوعود بطريقة أبسط۔

يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔

YouTube Video