تخيل القيام بـ 10 مهام بشكل مستمر ؛ ربما لا نتعب بعد هذه المهام العشر ، ولكن ماذا عن 50 مهمة أو 100 مهمة؟ لا يمكننا حتى القيام بهذا القدر من المهام بشكل مستمر وبدون جدولة.

ولكن هناك حل واحد لذلك ، وهو تحديد المواعيد. من خلال الجدولة ، يمكننا القيام بأي قدر من المهام بسهولة ، وسنعمل على زيادة إنتاجيتنا. على سبيل المثال ، بعد كل 10 مهام ، نأخذ قسطًا من الراحة لمدة 5 دقائق ، أو أفضل من ذلك ، يمكننا الاستمرار في أداء المهام حتى نتعب ، ثم نأخذ قسطًا من الراحة ونستمر في القيام ببقية المهام.

الجدولة في الويب

الشيء نفسه ينطبق على جافا سكريبت. على سبيل المثال ، هذا الرمز سوف يحظر موضوعنا لمدة 5 ثوان ، وسوف يتوقف كل شيء عن العمل.

let current = Date.now()
while (Date.now() < current + 5 * 1000) {
	console.log(`I'm blocking your thread for 5sec`)
}

لكن هذا ليس عدلاً ، لأنه ليس عملاً شاقًا. يمكن للمكتبات مثل Reactjs التعامل مع أعمال أثقل بمقدار 100 مرة دون حظر المتصفح. والسبب هو أن مثل هذه المكتبات تستخدم الجدولة.

الجدولة

الجدولة حول:

  • قائمة انتظار العمل: قائمة الأعمال التي نريد جدولتها وإنجازها
  • المهام الصغيرة والكبيرة: نوعان مختلفان من المهام يمكننا نقل المهام الخاصة بنا إلى إحدى هذه المراحل ، بحيث يتعامل معها المتصفح لاحقًا (مهمة صغيرة) أو على الفور (مهمة أو مهمة ماكرو)

“أولاً ، في كل مرة يتم فيها إنهاء مهمة (مهمة ماكرو) ، تتحقق حلقة الحدث لمعرفة ما إذا كانت المهمة تعيد التحكم إلى تعليمات JavaScript البرمجية الأخرى. إذا لم يكن الأمر كذلك ، فسيتم تشغيل جميع المهام الدقيقة في قائمة انتظار المهام الدقيقة. تتم معالجة قائمة انتظار المهام الدقيقة عدة مرات لكل تكرار لحلقة الحدث ، بما في ذلك بعد معالجة الأحداث وعمليات الاسترجاعات الأخرى.”

حان الوقت الآن لجدولة بعض الأشياء ، دعنا نرى.

تنفيذ

قبل أي شيء، تخيل أن لدينا العديد من أصناف العمل المهمة في قائمة انتظار لدينا ، مثل هذا:

function expensive() {
  console.log('I wanna block the event loop')
}
const workQueue = new Array(1000000).fill(expensive); // [expensive, expensive, ...]
// 1000000 amount of work units 🤯🤯
// workQueue.map(job => job()) will destroy the event loop and everything will stop working

إذا أردنا جدولة هذه الأقسام، فعلينا النظر في أمرين: أولا، موعد نهائي إنطلاق وتشغيل الأقسام. إذا تم ذلك ، فإننا نستسلم للمتصفح للتعامل مع أحداث إدخال المستخدم ثم نعود لتشغيل باقي الوحدات ؛ ثانيًا ، حدث إدخال المستخدم (النقر ، الكتابة ، …) عند تشغيل الأقسام ، لذلك نعود فورًا إلى المتصفح مرة أخرى ، للتحقق مما إذا كان لدينا أحداث إدخال المستخدم ، نستفيد isInputPending.

دعنا نحدد وقت الموعد النهائي ، والذي أفضل تعيينه كإطار واحد.

const DEADLINE_TIME = 1000 / 60 // 1000ms / 60frames

إنشاء دالة الجدولة

في الوقت الحالي ، نحتاج إلى إنشاء دالة الجدولة.

function schedule() {
  const DEADLINE = performance.now() + DEADLINE_TIME;
  while (workQueue.length > 0) {
    if (navigator?.scheduling?.isInputPending() || performance.now() >= DEADLINE) {
      // Yield to the browser if we have to handle an input event, or we're out of time.
      setTimeout(schedule); // re-running the schedule function later as a macro task
      return; // stop
    }
	// execute the current work unit 
    let job = workQueue.shift();
    job();
  }
}

لذلك إذا كان لدينا حدث إدخال مستخدم في انتظار أو نفد الوقت ، فإننا نضع وظيفة الجدول الزمني لدينا على جزء مختلف من حلقة الحدث (setTimeout) ، بحيث يمكن للمتصفح التعامل مع حدث الإدخال والأشياء الأخرى التي تسبقه ؛ بعد ذلك ، سيتم إعادة تشغيله والسماح لوظيفة الجدولة بتنفيذ باقي الوحدات إن أمكن.

الآن ، إذا حاولت تشغيل وظيفة الجدول الزمني ، فلن يمنع مليون سجل كل شيء من العمل ، وسيعمل كل شيء بشكل جيد.

schedule()

هذا كان كل شيء، سهل وسريع!

آمل أن يحظى هذا المقال بإعجابكم.

محمدباقر عبيات

The one Who loves solving stuff and writing about them.

منشور ذات صلة
هز الأشجار (tree shaking) 2 Minutes

شجرة تهز الخير!

محمدباقر عبيات

هز الأشجار هو مصطلح شائع الاستخدام في سياق جافا سكريبت لإزالة الشفرة الميتة. يعتمد على الهيكل الثابت لبناء جملة الوحدة ES2015، أي الاستيراد والتصدير. تم تعميم الاسم والمفهوم من خلال مجموعة تجميع وحدة ES2015.

Vanilla JS 9 Minutes

محاكاة React و JSX في Vanilla JS

جاسم ناظري

JSX بسيط للغاية. تكتب كود HTML عادي وتضخ البيانات من الكائن عن طريق إضافة أقواس متعرجة. سيتم تنفيذ كود JavaScript بين الأقواس وسيتم إدراج القيمة في DOM الناتج.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

السلة