مستوى المقال: متوسط — محتاج تكون كتبت JavaScript قبل كده وتعرف setTimeout و Promise شكلهم إيه، بس مش لازم تكون فاهم الـ Event Loop. هنبدأ بمثال بسيط جدًا للمبتدئ ثم نرجع للتفصيل العلمي.
الـ Event Loop في JavaScript: ليه setTimeout بصفر بيتأخّر عن Promise؟
لو كتبت setTimeout(fn, 0) وفاكر إنه هيشتغل قبل أي حاجة، الكود ده هيطلّع لك ترتيب مقلوب عن توقعك. بعد المقال ده هتعرف بالظبط ليه الـ Promise.then بيسبق الـ setTimeout حتى لو الاتنين "جاهزين"، وهتقدر تتنبأ بترتيب تنفيذ أي كود async من غير ما تشغّله.
المشكلة باختصار
JavaScript بتشتغل على thread واحد فقط. يعني سطر واحد بيتنفّذ في اللحظة. لكن المتصفح والـ Node بيخلّوك تكتب كود "متزامن المظهر" يستنى عمليات بطيئة (طلب شبكة، تايمر، قراءة ملف) من غير ما يجمّد الصفحة. اللي بيدير ده كله اسمه الـ Event Loop. سوء فهم ترتيبه بيسبّب bugs غريبة: قيمة بتتحدّث في الوقت الغلط، أو UI بيتجمّد بدون سبب واضح.
المفهوم بمثال بسيط: الكاشير والطابورين
تخيّل كاشير واحد في سوبر ماركت. الكاشير ده هو الـ Call Stack: بيعمل حاجة واحدة بس في اللحظة. قدامه طابورين:
- طابور العملاء العاديين = الـ Task Queue (المهام الكبيرة / macrotasks). ده مكان ال_setTimeout:
setTimeout. - طابور VIP = الـ Microtask Queue (المهام الصغيرة). ده مكان الـ
Promise.then.
القاعدة عند الكاشير صارمة: قبل ما يستدعي أي عميل عادي جديد، لازم يخلّص كل الـ VIP اللي مستنيين الأول. حتى لو دخل VIP جديد وهو بيخدم VIP، بيخدمه قبل ما يلتفت للطابور العادي. ده بالظبط ليه الـ Promise بيسبق الـ setTimeout.
الشرح العلمي: ثلاث قطع بتتحرك
دلوقتي نرجع للتعريف الدقيق. في كل دورة (tick) الـ Event Loop بيشتغل بالترتيب ده:
- Call Stack: ينفّذ كل الكود المتزامن (synchronous) لحد ما الستاك يفضى.
- Microtask Queue: يفرّغ كل الـ microtasks بالكامل (
Promise.then،queueMicrotask،awaitاللي بعد resolve). ولو microtask ولّدت microtask تانية، دي كمان بتتنفّذ في نفس الدورة. - Render: في المتصفح، هنا بس ممكن يحصل إعادة رسم للشاشة.
- Task Queue: ياخد مهمة واحدة بس (زي callback بتاع
setTimeout) ثم يرجع من أول الخطوة 2.
النقطة المفصلية: الـ microtasks بتتفرّغ بالكامل بين كل macrotask والتانية. المتصفح مش بيعمل render أصلًا وسط الـ microtasks. (المصدر: مواصفة WHATWG HTML، قسم event loops، وتوثيق MDN).