المهام الصغرى والوعود
تعلّموا سبب تشغيل عمليات استدعاء الوعود أولًا.
المهام الصغرى والوعود درس مجاني في JavaScript Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في JavaScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة JavaScript Academy 4 دروس في المجموع.
ما هي المهمة المصغّرة؟
المهمة المصغّرة هي مهمة مؤجلة ذات أولوية عالية. تؤدي دوال استدعاء Promise (.then و.catch و.finally) وqueueMicrotask إلى جدولة مهام مصغّرة.
القاعدة الأساسية: بعد كل تنفيذ متزامن، تُفرَّغ جميع المهام المصغّرة قبل أي مهمة كبرى.
دوال استدعاء Promise مؤجلة
حتى Promise الذي تمت تسويته مسبقًا يجدول دالة .then الخاصة به كمهمة مصغّرة. فهي لا تُنفَّذ بشكل متزامن.
console.log('start');
Promise.resolve().then(() => console.log('promise then'));
console.log('end');المهام المصغّرة تسبق المهام الكبرى
هذه هي أهم قاعدة للترتيب. تُنفَّذ دالة استدعاء Promise قبل دالة استدعاء setTimeout، حتى إذا تمت جدولة المؤقت أولًا.
setTimeout(() => console.log('timeout (macro)'), 0);
Promise.resolve().then(() => console.log('promise (micro)'));
console.log('sync');تُفرَّغ قائمة المهام المصغّرة بالكامل
تُفرغ حلقة الأحداث قائمة المهام المصغّرة بالكامل قبل الانتقال إلى المهمة الكبرى التالية. تُنفَّذ دوال استدعاء Promise المتعددة معًا أثناء عملية الإفراغ هذه.
setTimeout(() => console.log('macro'), 0);
Promise.resolve().then(() => console.log('micro 1'));
Promise.resolve().then(() => console.log('micro 2'));
console.log('sync');Promises المتسلسلة
تجدول كل دالة .then في السلسلة مهمة مصغّرة جديدة عند استقرار المهمة السابقة. ومع ذلك، تُنفَّذ جميعها قبل أي مؤقت معلّق.
setTimeout(() => console.log('timeout'), 0);
Promise.resolve()
.then(() => console.log('then 1'))
.then(() => console.log('then 2'))
.then(() => console.log('then 3'));
console.log('sync');جدولة مهام مصغّرة أثناء الإفراغ
إذا جدولت مهمة مصغّرة مهمةً مصغّرة أخرى، تُنفَّذ المهمة الجديدة أيضًا أثناء عملية الإفراغ نفسها، قبل أي مهمة كبرى. وتستمر القائمة في الإفراغ حتى تصبح فارغة تمامًا.
Promise.resolve().then(() => {
console.log('micro A');
Promise.resolve().then(() => console.log('micro B (added later)'));
});
setTimeout(() => console.log('macro'), 0);
console.log('sync');تنتقل القيم المُسوّاة عبر السلسلة
تصبح القيمة التي تُرجعها دالة معالجة .then مدخلًا لدالة المعالجة التالية في السلسلة، وكل ذلك عبر مهام مصغّرة.
Promise.resolve(2)
.then(n => n * 3)
.then(n => n + 1)
.then(n => console.log('result', n));
console.log('sync first');يستخدم async/await المهام المصغّرة
يُستأنف تنفيذ التعليمات التي تأتي بعد await كمهمة مصغّرة. لذلك يُنفَّذ استئناف التنفيذ بعد الانتظار قبل مؤقت تمت جدولته مسبقًا.
async function run() {
console.log('a');
await null;
console.log('c (after await)');
}
setTimeout(() => console.log('d (timeout)'), 0);
run();
console.log('b');عرض توضيحي للترتيب الكامل
لنجمع كل ذلك معًا. توقّع الترتيب: التنفيذ المتزامن أولًا، ثم جميع المهام المصغّرة، ثم المهمة الكبرى.
console.log('1 sync');
setTimeout(() => console.log('5 timeout'), 0);
Promise.resolve().then(() => console.log('3 promise'));
Promise.resolve().then(() => console.log('4 promise'));
console.log('2 sync');لماذا يُعدّ استنزاف المهام المصغّرة محفوفًا بالمخاطر؟
بما أن المهام المصغّرة تُنفَّذ دائمًا قبل المهام الكبرى، فإن المهمة المصغّرة التي تجدول مهام مصغّرة إضافية بلا نهاية يمكنها منع المؤقتات والعرض من التنفيذ. احرص على أن تكون سلاسل المهام المصغّرة محدودة.
let n = 0;
function loop() {
if (n++ < 3) {
console.log('micro ' + n);
Promise.resolve().then(loop);
}
}
setTimeout(() => console.log('macro after micros'), 0);
loop();لماذا يهم هذا الترتيب؟
إن معرفة أن المهام المصغّرة تُنفَّذ قبل المهام الكبرى تفسّر سبب ظهور نتائج Promise قبل دوال استدعاء المؤقتات، وسبب حدوث أخطاء الترتيب. القاعدة بسيطة: التنفيذ المتزامن، ثم إفراغ جميع المهام المصغّرة، ثم مهمة كبرى واحدة، ثم التكرار.
console.log('A');
Promise.resolve().then(() => console.log('B'));
setTimeout(() => console.log('D'), 0);
console.log('C');تحقق سريع
هناك دالة .then خاصة بـ Promise واستدعاء setTimeout(fn, 0) معلّقان معًا. أيهما يُنفَّذ أولًا؟
مراجعة: المهام المصغّرة وPromises
لقد تعلّمت قاعدة الأولوية:
- تنشأ المهام المصغّرة من Promises و
queueMicrotask. - تُفرَّغ قائمة المهام المصغّرة بأكملها قبل أي مهمة كبرى.
- تُعدّ عمليات الاستئناف في
async/awaitمهام مصغّرة. - يمكن لسلاسل المهام المصغّرة التي لا تنتهي أن تمنع المؤقتات والعرض من التنفيذ.
الأسئلة الشائعة
هل درس «المهام الصغرى والوعود» مجاني؟
نعم — نص درس «المهام الصغرى والوعود» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة JavaScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة JavaScript Academy 4 دروس في المجموع.
ماذا ستتعلم في «المهام الصغرى والوعود»؟
تعلّموا سبب تشغيل عمليات استدعاء الوعود أولًا. تتمرن على JavaScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ JavaScript Academy؟
لا تُشترط خبرة سابقة. JavaScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «المهام الصغرى والوعود»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس JavaScript Academy هذا؟
نعم. كل درس في JavaScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- مكدس الاستدعاءات
- المهام الكبرى وقائمة المهام
- المهام الصغرى والوعود
- queueMicrotask وترتيب التنفيذ