async و await
تجعل دالة async الخطوات غير المتزامنة سهلة القراءة من الأعلى إلى الأسفل. ينتظر await Promise داخل تلك الدالة فقط، ولا يجمّد الصفحة أو بقية JavaScript.
ما الذي يوقفه await؟
عند الوصول إلى await تعيد الدالة التحكم إلى المتصفح. يمكن للأحداث والأكواد الأخرى أن تعمل، ثم تتابع الدالة من الموضع نفسه بعد تحقق Promise.
استدعاء async يعيد Promise دائماً
حتى إن أعادت الدالة نصاً، فإن استدعاءها يعيد Promise يتحقق بذلك النص. وإذا رمت الدالة خطأً يُرفض Promise.
اقرأ النتيجة بعد await
تعيد pour كائن Promise. تكتب serve القيمة waiting، ثم تنتظر، وبعدها تستقبل lida tea.
function pour(order) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
if (order === "") reject("no leaves");
else resolve(order + " tea");
}, 100);
});
}
async function serve() {
console.log("waiting");
let drink = await pour("lida");
console.log(drink);
}
serve();
يظهر waiting ثم lida tea. السطران داخل serve، لكن الثاني يعمل بعد تحقق Promise.
المستدعي يحصل على Promise
لا يعطي استدعاء serve() بلا await المشروب مباشرة.
async function serve() {
return "lida tea";
}
let ticket = serve();
console.log(ticket instanceof Promise);
الناتج true لأن ticket هو Promise. اقرأ قيمته لاحقاً بواسطة await داخل دالة async أخرى أو بواسطة then.
عالج الرفض باستخدام try و catch
يتصرف رفض Promise المنتظر كخطأ عند تعبير await. ضع العملية داخل try واقرأ السبب في catch.
function pour(order) {
return order === ""
? Promise.reject("no leaves")
: Promise.resolve(order + " tea");
}
async function serveEmpty() {
try {
await pour("");
} catch (reason) {
console.log(reason);
}
}
serveEmpty();
الناتج no leaves. وأي خطأ تالٍ داخل كتلة try نفسها يصل أيضاً إلى catch.
تستمر بقية الصفحة
يتوقف تنفيذ دالة async الحالية وحدها. يعيد استدعاؤها Promise فوراً، ولذلك يستطيع الكود المتزامن التالي أن يعمل.
مثال كامل في المتصفح
يسجل المثال المراحل داخل دالة async واحدة، ويحل Promise بمؤقت قصير كي يعمل المثال بلا خادم.
<!DOCTYPE html>
<html>
<body>
<p id="cup">blank</p>
<p id="line">…</p>
<script>
function pour(order) {
return new Promise(resolve => setTimeout(() => resolve(order + " tea"), 100));
}
async function serve() {
const cup = document.getElementById("cup");
const seen = ["waiting"];
cup.textContent = "waiting";
const drink = await pour("lida");
cup.textContent = drink;
seen.push(drink, "done");
document.getElementById("line").textContent = seen.join(" / ");
}
serve();
</script>
</body>
</html>
السطر النهائي هو waiting / lida tea / done. لا تُضاف done إلا بعد كتابة القيمة المنتظرة.
جرّب بنفسك
غيّر الاسم lida وانتظر النتيجة، ثم مرّر نصاً فارغاً وتأكد أن catch يستقبل no leaves.
أخطاء شائعة
لا تتوقع نصاً جاهزاً من استدعاء async، ولا تكتب await داخل دالة عادية، ولا تفترض أن await يوقف الصفحة كلها.
الخلاصة
تعيد async دائماً Promise. يوقف await تلك الدالة فقط حتى يستقر Promise. استخدم try/catch للعملية التي قد تُرفض.
🧠 اختبر معرفتك
اختبر معرفتك
تحدى نفسك مع هذا الاختبار التفاعلي واكتشف مدى فهمك للموضوع
📝 التعليمات
- اقرأ كل سؤال بعناية
- اختر أفضل إجابة لكل سؤال
- يمكنك إعادة الاختبار عدة مرات كما تريد
- سيتم عرض تقدمك في الأعلى