نموذج تنفيذ JavaScript دقيق ويسهل فهمه. يمكن أن يساعدك التعرف على حلقة الحدث في جوهرها.

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

ما هي حلقة حدث JavaScript؟

حلقة حدث JavaScript هي آلية تعمل في خلفية كل تطبيق JavaScript. يسمح لـ JavaScript بمعالجة المهام بالتسلسل دون حظر سلسلة التنفيذ الرئيسية الخاصة بها. يشار إلى هذا باسم البرمجة غير المتزامنة.

تحتفظ حلقة الحدث بقائمة انتظار من المهام للتشغيل وتغذي تلك المهام إلى اليمين واجهة برمجة تطبيقات الويب لتنفيذ واحد تلو الآخر. تقوم JavaScript بتتبع هذه المهام وتعالج كل منها وفقًا لمستوى تعقيد المهمة.

لفهم الحاجة إلى حلقة حدث JavaScript والبرمجة غير المتزامنة. أنت بحاجة إلى فهم المشكلة التي تحلها بشكل أساسي.

خذ هذا الرمز ، على سبيل المثال:

functionlongRunningFunction() {
// This function does something that takes a long time to execute.
for (var
instagram viewer
i = 0; i < 100000; i++) {
console.log("Hello")
}
}

functionshortRunningFunction(a) {
return a * 2 ;
}

functionmain() {
var startTime = Date.now();
longRunningFunction();

var endTime = Date.now();

// Prints the amount of time it took to execute functions
console.log(shortRunningFunction(2));
console.log("Time taken: " + (endTime - startTime) + " milliseconds");
}

main();

يحدد هذا الرمز أولاً وظيفة تسمى longRunningFunction (). ستؤدي هذه الوظيفة نوعًا من المهام المعقدة التي تستغرق وقتًا طويلاً. في هذه الحالة ، يتم تنفيذ ملف ل حلقة تتكرر أكثر من 100000 مرة. هذا يعني ذاك console.log ("مرحبًا") يعمل 100000 مرة.

اعتمادًا على سرعة الكمبيوتر ، قد يستغرق هذا وقتًا طويلاً ويتم حظره وظيفة تشغيل قصيرة () من التنفيذ الفوري حتى اكتمال الوظيفة السابقة.

بالنسبة إلى السياق ، إليك مقارنة بين الوقت المستغرق لتشغيل كلتا الوظيفتين:

ثم العازبة وظيفة تشغيل قصيرة ():

يتضح الفرق بين عملية تبلغ 2351 مللي ثانية وعملية مدتها 0 مللي ثانية عندما تهدف إلى إنشاء تطبيق عالي الأداء.

كيف تساعد حلقة الحدث في أداء التطبيق

تحتوي حلقة الحدث على مراحل وأجزاء مختلفة تساهم في جعل النظام يعمل.

ذا كول ستاك

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

مكدس الاستدعاءات مسؤول عن الحفاظ على سياق التنفيذ والترتيب الصحيح للوظائف. يقوم بذلك عن طريق العمل كمكدس Last-In-First-Out (LIFO).

هذا يعني أن إطار الوظيفة الأخير الذي يدفعه برنامجك إلى مكدس الاستدعاءات سيكون أول من يخرج من المكدس ويتم تشغيله. سيضمن ذلك احتفاظ JavaScript بالترتيب الصحيح لتنفيذ الوظائف.

ستقوم JavaScript بإخراج كل إطار من المكدس حتى يصبح فارغًا ، مما يعني انتهاء تشغيل جميع الوظائف.

واجهة برمجة تطبيقات الويب Libuv

في صميم برامج جافا سكريبت غير المتزامنة libuv. مكتبة libuv مكتوبة بلغة البرمجة C ، والتي يمكن أن تتفاعل مع نظام التشغيل واجهات برمجة التطبيقات منخفضة المستوى. ستوفر المكتبة العديد من واجهات برمجة التطبيقات التي تسمح بتشغيل تعليمات JavaScript البرمجية بالتوازي مع غيرها شفرة. واجهات برمجة التطبيقات لإنشاء سلاسل رسائل ، وواجهة برمجة تطبيقات للتواصل بين سلاسل الرسائل ، وواجهة برمجة تطبيقات لإدارة مزامنة مؤشرات الترابط.

على سبيل المثال ، عند استخدام ملفات setTimeout في Node.js لإيقاف التنفيذ مؤقتًا. يتم إعداد المؤقت من خلال libuv ، والذي يدير حلقة الحدث لتنفيذ وظيفة رد الاتصال بمجرد مرور التأخير المحدد.

وبالمثل ، عند إجراء عمليات الشبكة بشكل غير متزامن ، يتعامل libuv مع هذه العمليات في ملف بطريقة تضمن أن المهام الأخرى يمكن أن تستمر في المعالجة دون انتظار عملية الإدخال / الإخراج (I / O) إلى نهاية.

رد الاتصال والحدث

قائمة انتظار رد الاتصال والحدث هي المكان الذي تنتظر فيه وظائف رد الاتصال التنفيذ. عند اكتمال عملية غير متزامنة من libuv ، تتم إضافة وظيفة رد الاتصال المقابلة إلى قائمة الانتظار هذه.

إليك كيف يسير التسلسل:

  1. تنقل JavaScript المهام غير المتزامنة إلى libuv لتتعامل معها ، وتستمر في التعامل مع المهمة التالية على الفور.
  2. عندما تنتهي المهمة غير المتزامنة ، تضيف JavaScript وظيفة رد الاتصال الخاصة بها إلى قائمة انتظار رد الاتصال.
  3. يستمر JavaScript في تنفيذ المهام الأخرى في مكدس الاستدعاءات حتى يتم الانتهاء من كل شيء بالترتيب الحالي.
  4. بمجرد أن يصبح مكدس الاستدعاءات فارغًا ، تنظر JavaScript في قائمة انتظار رد الاتصال.
  5. إذا كان هناك رد اتصال في قائمة الانتظار ، فإنه يدفع الأول إلى مكدس المكالمات وينفذها.

بهذه الطريقة ، لا تحظر المهام غير المتزامنة الخيط الرئيسي ، وتضمن قائمة انتظار رد الاتصال تنفيذ عمليات الاسترجاعات المقابلة بالترتيب الذي أكملته.

دورة تكرار الأحداث

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

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

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

بدون المهام الدقيقة ، ستعمل حلقة الحدث لهذه المهمة على النحو التالي:

  1. يقوم المستخدم بالنقر فوق الزر بشكل متكرر.
  2. تؤدي كل نقرة زر إلى تشغيل عملية جلب بيانات غير متزامنة.
  3. عند اكتمال عمليات جلب البيانات ، تضيف JavaScript عمليات الاسترجاعات المقابلة إلى قائمة انتظار المهام العادية.
  4. تبدأ حلقة الحدث في معالجة المهام في قائمة انتظار المهام العادية.
  5. يتم تنفيذ تحديث واجهة المستخدم استنادًا إلى نتائج جلب البيانات بمجرد أن تسمح المهام العادية بذلك.

ومع ذلك ، مع المهام الدقيقة ، تعمل حلقة الحدث بشكل مختلف:

  1. ينقر المستخدم على الزر بشكل متكرر ويبدأ عملية جلب البيانات غير المتزامنة.
  2. عند اكتمال عمليات جلب البيانات ، تضيف حلقة الحدث عمليات الاسترجاعات المقابلة إلى قائمة انتظار المهام الدقيقة.
  3. تبدأ حلقة الحدث في معالجة المهام في قائمة انتظار المهام الدقيقة فورًا بعد إكمال المهمة الحالية (نقرة الزر).
  4. يتم تنفيذ تحديث واجهة المستخدم استنادًا إلى نتائج جلب البيانات قبل المهمة العادية التالية ، مما يوفر تجربة مستخدم أكثر استجابة.

هذا مثال على الكود:

const fetchData = () => {
returnnewPromise(resolve => {
setTimeout(() => resolve('Data from fetch'), 2000);
});
};

document.getElementById('fetch-button').addEventListener('click', () => {
fetchData().then(data => {
// This UI update will run before the next rendering cycle
updateUI(data);
});
});

في هذا المثال ، كل نقرة على زر "جلب" المكالمات ابحث عن المعلومة(). يتم جدولة كل عملية جلب بيانات باعتبارها مهمة دقيقة. استنادًا إلى البيانات التي تم جلبها ، يتم تنفيذ تحديث واجهة المستخدم على الفور بعد اكتمال كل عملية جلب ، قبل أي مهام عرض أو تكرار أحداث أخرى.

يضمن ذلك رؤية المستخدمين للبيانات المحدثة دون مواجهة أي تأخير بسبب مهام أخرى في حلقة الحدث.

يمكن أن يؤدي استخدام المهام الدقيقة في مثل هذه السيناريوهات إلى منع حدوث مشكلة في واجهة المستخدم وتوفير تفاعلات أسرع وأكثر سلاسة في تطبيقك.

الآثار المترتبة على Event Loop لتطوير الويب

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

يوفر Node.js كل ما تحتاجه ، بما في ذلك العاملين على الويب لتحقيق المزيد من التوازي خارج مؤشر ترابط JavaScript الرئيسي.