JavaScript / متقدم: الجدولة والواجهات الموثوقة / الدرس 13
حلقات الأحداث والمهام والمهام المصغرة
توقع الجدولة المرصودة دون اختراع طابور مؤقتات عالمي واحد. افصل وظائف ECMAScript من مهام المتصفح ونقاط المهام المصغرة وفرص العرض وسلوك Node.
في هذه الصفحة
أهداف الدرس
- تتبع الشيفرة المتزامنة ومتابعات الوعود.
- تمييز المهام والمهام المصغرة والعرض.
- إدراك التجويع وحدود الترتيب الخاصة بالبيئة.
تتعاون اللغة والبيئة
تصف ECMAScript الوظائف وقواعد التنفيذ ويدمجها المتصفح بحلقات ومصادر مهام ونقاط مهام مصغرة. يكون استدعاء المؤقت مهمة في نموذج المتصفح، وتستخدم تفاعلات الوعد وqueueMicrotask الجدولة المصغرة. لا يصح افتراض طابور FIFO عالمي لكل نشاط. ولـNode مراحل ومرافق أخرى. تعلم ضمانات المثال بدلاً من نقل رسم بيئة واعتباره مواصفة اللغة لكل مكان.
تتبع الدور قبل المؤقت
ينفذ البرنامج عباراته المتزامنة أولاً. يجدول الوعد الموفى تفاعلاً، ويحدد المؤقت أهلية لاحقة ولا يقاطع البرنامج النشط. بعد العمل المتزامن يعمل التفاعل المصغر قبل المؤقت في المثال المضبوط. لا يعني تأخير صفر موعد تنفيذ دقيقاً أو رسماً قبله. النتيجة ملاحظات بشروط معلومة لا برهاناً على ترتيب الشبكة والعرض أو nextTick الخاصة بـNode الغائبة عن المقطع.
console.log("start");
setTimeout(() => console.log("timer"), 0);
Promise.resolve().then(() => console.log("promise"));
console.log("end");
start
end
promise
timer
لا يقاطع المؤقت البرنامج الحالي. يتحقق هذا الترتيب المحدود في Node ومتصفح محلي دون ادعاء تطابق حلقتيهما.
قد تضيف المهمة المصغرة مهام أخرى
تعالج نقطة الفحص المهام المصغرة حتى يفرغ الطابور بما فيها المضافة حديثاً. لذلك قد تسبق queueMicrotask متداخلة مؤقتاً سجل أولاً. وينشأ خطر تجويع؛ فالإضافة المستمرة تمنع المهام الأخرى وفرص العرض. ليس تكرار الوعود تسليماً عاماً للرسم. قد تكون السلسلة غير متزامنة للمستدعي لكنها تعطل الواجهة. حدّ العمل واختر حد جدولة مناسباً حين يحتاج المستخدم وقتاً.
تتبع ترتيب الإضافة صراحة
يضيف المثال A وB أثناء البرنامج. تضيف A عند عملها C بعد B الموجودة. ويبقى المؤقت بعد نقطة الفحص المنتهية. اكتب تتبع الطابور: حدّد العامل ثم ما يضيفه. لا تستنتج الترتيب من الإزاحة أو كلفة ظاهرية. عبّر عن الاعتماد الحقيقي بوعد معاد أو حالة صريحة بدلاً من سباق مؤقت عرضي يتغير بحمل البيئة والشيفرة المحيطة.
queueMicrotask(() => {
console.log("A");
queueMicrotask(() => console.log("C"));
});
queueMicrotask(() => console.log("B"));
setTimeout(() => console.log("T"), 0);
A
B
C
T
تضاف C خلف B. يتوقف المثال عمداً عن الإضافة فيسمح للمؤقت بالعمل.
الترتيب ليس ميزانية أداء
قد يطول الاستدعاء رغم صحة ترتيبه. قس زمن العمل المتزامن وحجمه ثم قلله أو انقل الحساب الملائم إلى عامل. يختار المتصفح فرص العرض؛ فلا تفترض رسماً لكل مؤقت أو إطاراً لكل وعد. تنسق requestAnimationFrame مع فرصة عرض لكن الحساب المكلف داخلها قد يفوّت إطاراً. راقب حالة مفيدة واستخدم جدولة مضبوطة للسباق بدلاً من مللي ثوان دقيقة تختلف بالجهاز والتبويب الخلفي.
الأخطاء الشائعة وإصلاحها
اعتبار مؤقت الصفر فورياً
- لماذا يحدث؟
- الخلط بين تأخير الأهلية والموعد المضمون.
- كيف تصلحه؟
- التعبير عن الاعتماد ورصد الاكتمال صراحة.
- كيف تتجنب تكراره؟
- تجنب تحققات توقيت دقيق للجدولة العادية.
استخدام await متكررة لضمان الرسم
- لماذا يحدث؟
- الخلط بين المتابعة المصغرة والعودة لمهام أخرى.
- كيف تصلحه؟
- تحديد العمل واستخدام حد جدولة متصفح مناسب.
- كيف تتجنب تكراره؟
- قياس الاستجابة لا عدد كلمات await.
تطبيق رسم طابور المتصفح على Node مباشرة
- لماذا يحدث؟
- إغفال مراحل وواجهات البيئة الخاصة.
- كيف تصلحه؟
- تحديد البيئة وحصر ادعاء الترتيب بالمضمون.
- كيف تتجنب تكراره؟
- إبقاء جدولة Node الخاصة في دورتها.
اختبر فهمك
1. لماذا تتبع C الحرف B في المثال المتداخل؟
اعرض الحل المشروح
كانت B في الطابور عند بدء A، وتلحق A الحرف C فتعالج B قبل C، ثم المؤقت هنا. هذا استدلال بالطابور لا ضمان ترتيب عالمي لمصادر المهام حسب التسجيل.
2. تتجمد صفحة في حلقة async تنتظر وعوداً موفاة تكراراً. فسّر.
اعرض الحل المشروح
قد تضيف كل متابعة عملاً مصغراً قبل فراغ نقطة الفحص فتؤخر المهام والعرض. قلل العمل وحدّه أو قسّمه عبر حدود مهام فعلية أو عامل لحساب مستقل مناسب. تحقق من تقدم مرئي بأحجام ممثلة.
أهم ما تعلمته
- المهمة والمهمة المصغرة مفهومان مختلفان تدمجهما البيئة.
- يفسر التتبع المنتهي الترتيب وتفسر الميزانيات المقاسة الاستجابة.