البرومس
مفهوم البرومس
الوعد أو البرومس ( Promise ) هو كائن و فيه دالة أوامرها تتنفذ بشكل متزامن، حيث أنه يكون متوقع أن تكون بحاجة لبعض الوقت حتى تتنفذ و ترجع النتيجة في النهاية. و في كلا الحالتين فإنك قادر على ترقب و معالجة ما سترجعه لك.
مفسّر الكود لا يقف عند تنفيذ البرومس، بل يكمل تننفيذ باقي الأوامر الموجودة بعده و يكون بذات الوقت يترقب النتيجة التي سيرجعها حتى يعالجها.
في هذا الدرس ستتعلم طريقة إنشاء برومس جديد، طريقة تنفيذه، و طريقة معالجة النتائج التي يرجعها.
خطوات إنشاء برومس و تنفيذه
بشكل عام، كائن البرومس يتم بناؤه بواسطة الكونستركتور
أسلوب إنشاء البرومس أمر قد تجده معقد جداً لأنه لا يشبه الطرق السابقة التي اعتدت على اتباعها في كتابة الكود، و لهذا سنشرحه على خطوات و من ثم نضع لك الشكل العام لإنشائه.
الآن سنقوم بتعريف دالة إسمها
الخطوة الأولى
function fetchData() {
return // هنا يجب أن نجعلها ترجع كائن يمثل البرومس
}
الآن سنجعل الدالة
الخطوة الثانية
function fetchData() {
return new Promise((resolve, reject) => {
// هنا يجب وضع كود البرومس
});
}
الآن سنحدد كيف سيتم إرجاع قيمة من البرومس مع تحديد ما إن كانت قيمة سليمة أم أنها قيمة تشير للخطأ الذي وقع عند تنفيذ البرومس.
في حال تم تمرير القيمة إلى الدالة
الخطوة الثالثة
function fetchData() {
return new Promise((resolve, reject) => {
// كود البرومس يبدأ من هنا
// القيمة التي نريد إرجاعها من البرومس في حال لم يحدث خطأ نمررها للدالة التالية
resolve(value);
// القيمة التي نريد إرجاعها من البرومس في حال حدوث خطأ نمررها للدالة التالية
reject(error);
});
}
في النهاية لتنفيذ أوامر البرومس علينا استدعاء الدالة
الخطوة الأخيرة
function fetchData() {
return new Promise((resolve, reject) => {
// كود البرومس يبدأ من هنا
// القيمة التي نريد إرجاعها من البرومس في حال لم يحدث خطأ نمررها للدالة التالية
resolve(value);
// القيمة التي نريد إرجاعها من البرومس في حال حدوث خطأ نمررها للدالة التالية
reject(error);
});
}
// هنا قمنا باستدعاء الدالة التي ترجع البرومس مع مراقبة نتائجها
fetchData().then(
(value) => { /* هنا نعالج النتيجة التي قد يرجعها البرومس */ },
(error) => { /* هنا نعالج الخطأ الذي قد يرجعه البرومس */ }
);
أسماء الدوال
مثال عملي حول البرومس
في المثال التالي قمنا بإنشاء برومس يعطينا رقم عشوائي بين 1 و 10 بعد مرور ثانية واحدة.
الرقم الذي يعطينا إياها سنعتبره مقبولاً إن كان أكبر أو يساوي 5، و سنعتبره مرفوضاً إن لم يكن كذلك.
نتيجة تنفيذ البرومس سنعرضها باللون الأخضر إن كانت مقبولة، و باللون الأحمر إن لم تكن كذلك.
مثال
<!DOCTYPE html>
<html>
<body>
<h1>Javascript Promise</h1>
<p>Click on the button and wait for 1 second to execute the promise.</p>
<button onclick="executePromise()">Execute the promise</button>
<p id="demo"></p>
<script>
// هنا قمنا بتعريف دالة تقوم بإرجاع برومس عندما يتم استدعاءها
function fetchData() {
return new Promise((resolve, reject) => {
// هنا أنشأنا مؤقت لجعل تنفيذ أوامر البرومس يتم بعد مرور ثانية واحدة
setTimeout( () => {
// هنا قمنا بتعريف متغير قيمته عبارة عن عدد عشوائي بين 1 و 10
const value = Math.floor(Math.random() * 10) + 1;
// أكبر أو تساوي 5 فهي قيمة مقبولة value هنا إعتبرنا أنه إذا كانت قيمة المتغير
if (value >= 5) {
resolve(value);
}
// أكبر أو تساوي 5 فهي قيمة خاطئة value هنا إعتبرنا أنه إذا لم تكن قيمة المتغير
else {
reject(value);
}
}, 1000);
});
}
// سيتم تنفيذها عند النقر على الزر الموجود في الصفحة executePromise() الدالة
function executePromise() {
// لتنفيذ البرومس و الحصول على نتيجته then() و من ثم الدالة fetchData() هنا قمنا باستدعاء الدالة
fetchData().then(
// demo يساوي id إذا أرجع لنا قيمة سليمة فسيتم عرضها في العنصر الذي يملك
(value) => {
document.querySelector('#demo').innerHTML = 'Promise return ' + value;
document.querySelector('#demo').style.color = 'green';
},
// demo يساوي id إذا أرجع لنا قيمة تشير لخطأ فسيتم عرضها في العنصر الذي يملك
(error) => {
document.querySelector('#demo').innerHTML = 'Promise return ' + error;
document.querySelector('#demo').style.color = 'red';
}
);
}
</script>
</body>
</html>
معالجة جميع أخطاء البرومس
في حال أردت معالجة جميع الأخطاء التي قد تحدث عند تنفيذ البرومس و ليس فقط التي تحددها أنت بواسطة الدالة
مثال
<!DOCTYPE html>
<html>
<body>
<h1>Javascript Catch Promise Errors</h1>
<p>Click on the button and wait for 1 second to execute the promise.</p>
<button onclick="executePromise()">Execute the promise</button>
<p id="demo"></p>
<script>
// هنا قمنا بتعريف دالة تقوم بإرجاع برومس عندما يتم استدعاءها
function fetchData() {
return new Promise((resolve, reject) => {
// هنا أنشأنا مؤقت لجعل تنفيذ أوامر البرومس يتم بعد مرور ثانية واحدة
setTimeout( () => {
// هنا قمنا بتعريف متغير قيمته عبارة عن عدد عشوائي بين 1 و 10
const value = Math.floor(Math.random() * 10) + 1;
// أكبر أو تساوي 5 فهي قيمة مقبولة value هنا إعتبرنا أنه إذا كانت قيمة المتغير
if (value >= 5) {
resolve(value);
}
// أكبر أو تساوي 5 فهي قيمة خاطئة value هنا إعتبرنا أنه إذا لم تكن قيمة المتغير
else {
reject(value);
}
}, 1000);
});
}
// سيتم تنفيذها عند النقر على الزر الموجود في الصفحة executePromise() الدالة
function executePromise() {
// لتنفيذ البرومس fetchData() هنا قمنا باستدعاء الدالة
fetchData()
// للحصول على نتيجة تنفيذ البرومس then() هنا قمنا باستدعاء الدالة
.then((value) => {
// demo يساوي id إذا أرجع لنا قيمة سليمة فسيتم عرضها في العنصر الذي يملك
document.querySelector('#demo').innerHTML = 'Value returned = ' + value;
document.querySelector('#demo').style.color = 'green';
})
// للحصول على أي خطأ قد يحدث عند تنفيذ البرومس catch() هنا قمنا باستدعاء الدالة
.catch((error) => {
// demo يساوي id إذا أرجع لنا قيمة تشير لخطأ فسيتم عرضها في العنصر الذي يملك
document.querySelector('#demo').innerHTML = 'Error returned = ' + error;
document.querySelector('#demo').style.color = 'red';
});
}
</script>
</body>
</html>
المزيد حول بناء البرومس
في حال كان البرومس سيرجع فقط قيم مقبولة فإنه لا داعي أن يتم وضع الدالة
مثال
// هنا قمنا بتعريف دالة تقوم بإرجاع برومس عندما يتم استدعاءها
function fetchData() {
return new Promise((resolve) => {
// هنا نضع الكود المتوقع أن يستغرق تنفيذه بعض الوقت
// القيمة التي نريد إرجاعها من البرومس في حال لم يحدث خطأ نمررها للدالة التالية
resolve(value);
});
}
// هنا قمنا باستدعاء الدالة التي ترجع برومس مع مراقبة نتائجها
fetchData().then(
(value) => { /* هنا نعالج النتيجة التي قد يرجعها البرومس */ }
);
عند تنفيذ البرومس، يمكنك استخدام الدالة
في المثال التالي قمنا ببناء برومس يرجع قيمة عشوائية بين 1 و 10 عندما يتم تنفيذه.
مثال
<!DOCTYPE html>
<html>
<body>
<h1>Javascript Without A Reject Function</h1>
<p>Click on the button and wait for 1 second to execute the promise.</p>
<button onclick="executePromise()">Execute the promise</button>
<p id="demo"></p>
<script>
// هنا قمنا بتعريف دالة تقوم بإرجاع برومس عندما يتم استدعاءها
function fetchData() {
return new Promise((resolve) => {
// هنا أنشأنا مؤقت لجعل تنفيذ أوامر البرومس يتم بعد مرور ثانية واحدة
setTimeout( () => {
// هنا قمنا بتعريف متغير قيمته عبارة عن عدد عشوائي بين 1 و 10
const value = Math.floor(Math.random() * 10) + 1;
// value هنا قمنا بإرجاع قيمة
resolve(value);
}, 1000);
});
}
// سيتم تنفيذها عند النقر على الزر الموجود في الصفحة executePromise() الدالة
function executePromise() {
// لتنفيذ البرومس و الحصول على نتيجته then() و من ثم الدالة fetchData() هنا قمنا باستدعاء الدالة
fetchData()
// demo يساوي id إذا أرجع لنا قيمة سليمة فسيتم عرضها في العنصر الذي يملك
.then((value) => {
document.querySelector('#demo').innerHTML = 'Value returned = ' + value;
document.querySelector('#demo').style.color = 'green';
})
// للحصول على أي خطأ قد يحدث عند تنفيذ البرومس catch() هنا قمنا باستدعاء الدالة
.catch((error) => {
// demo يساوي id إذا أرجع لنا قيمة تشير لخطأ فسيتم عرضها في العنصر الذي يملك
document.querySelector('#demo').innerHTML = 'Error returned = ' + error;
document.querySelector('#demo').style.color = 'red';
});
}
</script>
</body>
</html>