نموذج التزامن JavaScript وحلقة الحدث

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

مكدس المكالمات

أولاً ، دعنا نتعرف على ماهية مكدس الاستدعاءات.

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

لنلقِ نظرة على مثال التعليمات البرمجية لفهم مكدس الاستدعاءات:

function multiply(x,y) { return x * y; } function squared(n) { return multiply(n,n) } function printSquare(n) { return squared(n) } let numberSquared = printSquare(5); console.log(numberSquared);

أولاً عند تنفيذ الكود ، سيقرأ وقت التشغيل من خلال كل تعريف من تعريفات الوظائف. ولكن عندما تصل إلى السطر الذي يتم فيه استدعاء الوظيفة الأولى printSquare (5) فإنها ستدفع هذه الوظيفة إلى مكدس الاستدعاءات.

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

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

أخيرًا ، ترجع الدالة التربيعية وتخرج من المكدس ثم ينطبق الأمر نفسه مع printSquare. يتم تخصيص القيمة التربيعية النهائية لمتغير numberSquared.

نواجه مرة أخرى استدعاء دالة (في هذه الحالة يكون عبارة console.log ()) لذلك يدفع وقت التشغيل هذا إلى المكدس. هذا ينفذه وبالتالي طباعة الرقم التربيعي على وحدة التحكم.

لاحظ أن الوظيفة الأولى التي يتم دفعها إلى المكدس قبل تشغيل أي من الكود أعلاه هي الوظيفة الرئيسية. في وقت التشغيل ، يُشار إلى هذا على أنه "وظيفة مجهولة".

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

يقوم مكدس الاستدعاءات فقط بتسجيل الوقت الذي يتم فيه تنفيذ الوظيفة. وهو يتتبع الوظيفة التي يتم تنفيذها حاليًا.

المتصفح

نعلم الآن من هذا أن Javascript يمكنها تنفيذ شيء واحد في كل مرة ولكن هذا ليس هو الحال مع المتصفح. يحتوي المتصفح على مجموعته الخاصة من واجهات برمجة التطبيقات مثل setTimeout و XMLHttpRequests التي لم يتم تحديدها في وقت تشغيل Javascript.

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

لنلق نظرة على الرسم التخطيطي لفهم الصورة كاملة.

نموذج التزامن وحلقة الحدث

يتم تقديم بعض المصطلحات الأخرى هنا ، لذا دعنا نراجعها:

الكومة : هي في الغالب المكان الذي يتم فيه تخصيص الكائنات.

قائمة انتظار رد الاتصال : إنها بنية بيانات تخزن جميع عمليات الاسترجاعات. نظرًا لأنها قائمة انتظار ، تتم معالجة العناصر استنادًا إلى ما يرد أولاً يصرف أولاً.

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

دعنا نفهم هذا بمثال رمز:

console.log('hi'); setTimeout(function() { console.log('freecodeCamp') },5000); console.log('JS')

عندما يتم تنفيذ السطر الأول فإنه يكون console.log (). هذا استدعاء للوظيفة مما يعني أنه يتم دفع هذه الوظيفة إلى مكدس الاستدعاءات حيث يتم تنفيذ طباعة "hi" على وحدة التحكم. أخيرًا يتم إرجاعه وإزالته من المكدس.

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

في هذه الأثناء بينما كان كل هذا يجري على انتهاء المؤقت. بعد انقضاء 5 ثوانٍ ، يمضي المتصفح قدمًا ويدفع وظيفة رد الاتصال إلى قائمة انتظار رد الاتصال.

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

مرة أخرى داخل الكود ، يوجد استدعاء console.log () لذلك تنتقل هذه الوظيفة إلى الجزء العلوي من المكدس وتنفذ والتي تسجل 'freecodecamp' في وحدة التحكم وأخيرًا تعود. هذا يعني أنه قد تم فصله عن المكدس وأخيراً تم إخراج رد الاتصال من المكدس وقد انتهينا.

لتصور هذا بشكل أفضل ، جرب هذه الأداة بواسطة Phillip Roberts: Loupe Event Loop Visualizer