محتويات الدورة

JavaScript / متوسط: الوحدات والعقود غير المتزامنة / الدرس 9

مسارات async والتسلسل والتنظيف

استخدم async وawait للتعبير عن الاعتماد دون فقد التزامن أو الأخطاء. قارن التسلسل والعمل المستقل والتنظيف حول إخفاق محلي مضبوط.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • شرح الوعد الذي تعيده async.
  • اختيار البدء المتتابع أو المتزامن عمداً.
  • استخدام try/catch/finally للعمليات المنتظرة.

توقف await متابعة هذا الاستدعاء

تعيد async وعداً دائماً حتى مع return لقيمة عادية. تلاحظ await قيمة أو thenable ثم تتابع الدالة على نحو غير متزامن، ولا تحجب خيط المتصفح كله انتظاراً للإدخال والإخراج. يعمل ما قبل التعليق أثناء الاستدعاء ويتلقى المستدعي وعداً. يصبح الرمي رفضاً له. الصياغة وسيلة لتركيب الاعتماد لا مفتاحاً يجعل الحساب الثقيل غير حاجب؛ فالحلقة المتزامنة داخل async ما زالت تحتل خيطها.

تسلسل المراحل المعتمدة

لا تنسق إيصالاً بهوية تسجيل قبل نجاح الإنشاء. انتظر النتيجة المطلوبة وتحقق منها ثم تابع. توفر المرحلة الأولى معرفاً مصطنعاً وتستخدمه الثانية؛ وتصل النتيجة عبر وعد async. افصل نتيجة المسار من عرض التقدم لإعادة الاستخدام. لا تحط كل مرحلة بـcatch تختلق قيمة طبيعية؛ فقد تستخدم المراحل التالية هوية خاطئة وتنتج تأكيداً مقنعاً زائفاً.

javascript يعيد المسار المعتمد وعداً
async function createEnrollment() { return { id: "E-7" }; }
async function receipt() {
  const enrollment = await createEnrollment();
  return "receipt:" + enrollment.id;
}
console.log(await receipt());
console.log(receipt() instanceof Promise);
الناتج المتوقع
receipt:E-7
true

تحصل await على التسجيل قبل تركيب الإيصال. ويعيد الاستدعاء دون انتظار Promise.

بدء العمل المستقل قبل انتظار الاثنين

إذا استقلت عمليتان فإن انتظار الأولى قبل بدء الثانية يفرض تسلسلاً غير لازم. ابدأهما وانتظر مجمعاً مناسباً إذا سمح العقد. لا يضمن البدء المتزامن تنفيذاً متوازياً أو سرعة؛ تقرر البيئة والموارد ذلك. حدّ التفرع للمدخلات الكبيرة حتى لا ترهق آلاف العمليات الذاكرة أو الاعتماد. لا تنتظر forEach استدعاءاتها async. استخدم for...of مع await للتتابع أو map إلى وعود وانتظر مجمعاً للتداخل المقصود.

تمتلك finally التنظيف لا نتيجة جديدة

استخدم try/catch حول رفض منتظر عندما تملك الطبقة الاستعادة. تفيد finally لتحرير الانشغال أو المورد، وتجنب عموماً return يستبدل النتيجة أو يخفي الخطأ. يسجل المثال البداية ويعالج الرفض المنتظر ويعيد حالة الخمول دائماً. إذا أعادت الدالة وعداً رافضاً داخل try دون انتظاره فلن تمسك catch المحلية رفضه اللاحق. قرر هل يحتاج التنظيف المحلي انتهاء العملية أم يملك المستدعي بقية عمر الوعد.

javascript إخفاق منتظر وتنظيف حتمي
const events = [];
async function run() {
  events.push("busy");
  try {
    await Promise.reject(new Error("unavailable"));
  } catch (error) {
    events.push(error.message);
  } finally {
    events.push("idle");
  }
}
await run();
console.log(events.join(","));
الناتج المتوقع
busy,unavailable,idle

يدخل الرفض catch وتعيد finally الحالة النهائية. يستعيد المثال عمداً بدلاً من إعادة الرمي.

تحتاج النتائج قواعد عمر وسباق أيضاً

قد تصل النتيجة بعد تغيير الدورة أو إغلاق العرض. لا تحل async التحديث القديم. اربط العمل بجيل طلب أو إشارة إلغاء مملوكة وتحقق من انتماء النتيجة للحالة النشطة قبل العرض. يقلل الإلغاء الهدر فقط إذا دعمته العملية، ويبقى حارس النتيجة القديمة مفيداً. عرّف التحميل والنجاح والخطأ وتأكد أن finally قديمة لا تمحو انشغال طلب أحدث. هذه قواعد تنسيق تطبيق لا تحل بإضافة await.

الأخطاء الشائعة وإصلاحها

انتهاء forEach قبل دوالها async

لماذا يحدث؟
عقدها لا ينتظر وعود الاستدعاء.
كيف تصلحه؟
اختيار for...of متتابعة أو map مع مجمع منتظر.
كيف تتجنب تكراره؟
التحقق من اكتمال المسار ورفضه.

إفلات رفض من catch محلية

لماذا يحدث؟
إعادة الوعد دون انتظاره داخل try.
كيف تصلحه؟
الانتظار حيث يلزم الرصد والاستعادة.
كيف تتجنب تكراره؟
اختبار اعتماد رافض لا النجاح فقط.

إزالة طلب قديم حالة تحميل حديثة

لماذا يحدث؟
تجاهل ملكية الطلب في التنظيف.
كيف تصلحه؟
حماية عرض النتيجة والتنظيف بالملكية الحالية.
كيف تتجنب تكراره؟
اختبار ترتيب اكتمال معكوس صريح.

اختبر فهمك

1. الملف الشخصي والفهرس مستقلان. كيف يبدأ تحميلهما؟

اعرض الحل المشروح

ابدأ العمليتين ثم انتظر all إن لزمتا أو allSettled إن سُمح بالجزئي. يداخل ذلك الانتظار ولا يضمن توازي JavaScript. أضف حداً للتزامن إذا توسع النمط لقائمة كبيرة.

2. نُقلت حلقة ثقيلة إلى async compute(). لماذا تتجمد الكتابة؟

اعرض الحل المشروح

تبقى الحلقة عملاً متزامناً بالخيط نفسه؛ فلا تنقلها async. قس المدة وقلل العمل أو قسّمه لمهام مناسبة أو استخدم عاملاً لحساب مستقل ملائم. تكرار انتظار وعد موفى ليس تسليماً موثوقاً للعرض.

أهم ما تعلمته

  • تعبر await عن اعتماد وتحفظ دلالات الوعد.
  • يبقى التزامن والإلغاء والملكية قرارات صريحة.

المراجع الرسمية