على الرغم من أن Javascript هي لغة ذات ترابط واحد، إلا أن Node.js يمكنها تعيين المهام لنظام التشغيل، مما يسمح لها بمعالجة مهام متعددة في نفس الوقت. يجب إكمال العديد من المهام في نفس الوقت لأن العمليات في نظام التشغيل متعددة الخيوط. تتم إضافة رد الاتصال المرتبط بكل عملية إلى قائمة انتظار الأحداث ويتم جدولته بواسطة Node.js للتشغيل عند اكتمال المهمة المحددة.
لكتابة كود Node.js فعال وموثوق، يجب أن يكون لدى المستخدم فهم قوي لحلقات الأحداث. يمكن أن يساعد أيضًا في استكشاف مشكلات الأداء وإصلاحها بشكل فعال. تعمل حلقة الأحداث في Node.js على حفظ الذاكرة وتسمح لك بالقيام بأشياء متعددة في وقت واحد دون الحاجة إلى الانتظار حتى انتهاء كل منها. يشير المصطلح 'غير متزامن' إلى أي وظيفة Javascript تعمل في الخلفية دون حظر الطلبات الواردة.
قبل الانتقال مباشرة إلى حلقات الأحداث، دعونا نلقي نظرة على الجوانب المختلفة للغة برمجة جافا سكريبت.
جافا سكريبت كلغة برمجة غير متزامنة
دعونا نلقي نظرة على مفاهيم البرمجة غير المتزامنة. يتم استخدام جافا سكريبت في تطبيقات الويب والجوال وسطح المكتب، ولكن تجدر الإشارة إلى أن جافا سكريبت هي لغة برمجة كمبيوتر متزامنة ذات خيط واحد.
يتم إعطاء مثال رمز بسيط لفهم هذا المفهوم.
طريقة الوظيفة1 ( ) {
وحدة التحكم. سجل ( 'الوظيفة 1' )
}
طريقة الوظيفة2 ( ) {
وحدة التحكم. سجل ( 'الوظيفة 2' )
}
طريقة 1 ( )
الطريقة2 ( )
في هذا الكود، يتم إنشاء وظيفتين بسيطتين ويتم استدعاء الطريقة 1 أولاً حتى يتم تسجيل الطريقة 1 أولاً ثم الانتقال إلى الوظيفة التالية.
انتاج |
جافا سكريبت كلغة برمجة متزامنة
جافا سكريبت هي لغة برمجة متزامنة وتقوم بتنفيذ كل سطر خطوة بخطوة من الأعلى إلى الأسفل مع تنفيذ سطر واحد فقط في المرة الواحدة. في رمز المثال الموضح أعلاه، يتم تسجيل الطريقة 1 أولاً في الجهاز ثم الطريقة 2.
جافا سكريبت كلغة حظر
كونها لغة جافا سكريبت متزامنة لديها وظيفة الحظر. لا يهم المدة التي يستغرقها إكمال العملية المستمرة ولكن لن تبدأ عملية جديدة إلا بعد اكتمال العملية السابقة. في مثال التعليمات البرمجية أعلاه، لنفترض أن هناك الكثير من التعليمات البرمجية في الطريقة 1 بغض النظر عن مقدار الوقت الذي يستغرقه إما 10 ثوانٍ أو دقيقة، ولن يتم تنفيذ الطريقة 2 حتى يتم تنفيذ جميع التعليمات البرمجية في الطريقة 1.
ربما واجه المستخدمون هذا أثناء التصفح. عندما يتم تنفيذ تطبيق ويب في متصفح ما في الواجهة الخلفية، يتم تنفيذ جزء كبير من التعليمات البرمجية بحيث يبدو المتصفح متجمدًا لبعض الوقت قبل إعادة وصول التحكم إلى المستخدم. يُعرف هذا السلوك بالحظر. لا يمكن للمتصفح قبول أي طلبات واردة أخرى حتى تتم معالجة الطلب الحالي.
جافا سكريبت هي لغة ذات ترابط واحد
لتشغيل برنامج في جافا سكريبت يتم استخدام وظيفة الموضوع. المواضيع قادرة فقط على أداء مهمة واحدة في كل مرة. تدعم لغات البرمجة الأخرى تعدد الخيوط ويمكنها تشغيل مهام متعددة بالتوازي، وتحتوي جافا سكريبت على مؤشر ترابط واحد فقط لتنفيذ أي برنامج نصي للتعليمات البرمجية.
في انتظار جافا سكريبت
كما هو واضح من الاسم في هذا القسم، علينا أن ننتظر حتى تتم معالجة طلبنا للمضي قدمًا. يمكن أن يستغرق الانتظار عدة دقائق لا يتم خلالها قبول أي طلب آخر. إذا استمر البرنامج النصي للتعليمات البرمجية دون انتظار، فسيواجه الرمز خطأً. يجب تنفيذ بعض الوظائف في Javascript أو بشكل أكثر تحديدًا Node.js لجعل التعليمات البرمجية غير متزامنة.
الآن بعد أن فهمنا الجوانب المختلفة لجافا سكريبت، دعونا نفهم المتزامن وغير المتزامن من خلال بعض الأمثلة البسيطة.
التنفيذ المتزامن للتعليمات البرمجية في جافا سكريبت
متزامن يعني أن التعليمات البرمجية يتم تنفيذها بشكل تسلسلي أو ببساطة خطوة بخطوة بدءًا من الأعلى والانتقال إلى الأسفل سطرًا تلو الآخر.
فيما يلي مثال يمكن أن يساعد في فهم:
// application.jsوحدة التحكم. سجل ( 'واحد' )
وحدة التحكم. سجل ( 'اثنين' )
وحدة التحكم. سجل ( 'ثلاثة' )
في هذا الكود، هناك ثلاث عبارات console.log كل منها يطبع شيئًا ما. أولاً، يتم إرسال البيان الأول الذي سيطبع 'واحد' في وحدة التحكم إلى مكدس الاستدعاءات لمدة 1 مللي ثانية (تقديريًا) ثم يتم تسجيله في الجهاز. بعد ذلك، يتم دفع العبارة الثانية إلى مكدس الاستدعاءات والآن يبلغ الوقت 2 مللي ثانية مع إضافة عبارة واحدة من العبارة السابقة ثم يتم تسجيل 'Two' إلى وحدة التحكم. أخيرًا، يتم دفع العبارة الأخيرة إلى مكدس الاستدعاءات في الوقت الحالي وهو 3 مللي ثانية ويتم تسجيل 'ثلاثة' في وحدة التحكم.
يمكن تنفيذ الكود أعلاه عن طريق استدعاء الأمر التالي:
تطبيق العقدة. jsانتاج |
تم شرح الوظيفة أعلاه بالتفصيل ومن خلال وضعها في الاعتبار، يتم تسجيل الإخراج في وحدة التحكم في غمضة عين:
التنفيذ غير المتزامن للتعليمات البرمجية في جافا سكريبت
الآن دعونا نعيد بناء نفس الكود من خلال تقديم عمليات الاسترجاعات وجعل الكود غير متزامن. يمكن إعادة بناء الكود أعلاه على النحو التالي:
// application.jsوظيفة طباعة واحدة ( أتصل مرة أخرى ) {
setTimeout ( وظيفة ( ) {
وحدة التحكم. سجل ( 'واحد' ) ;
أتصل مرة أخرى ( ) ;
} , 1000 ) ;
}
وظيفة الطباعة اثنان ( أتصل مرة أخرى ) {
setTimeout ( وظيفة ( ) {
وحدة التحكم. سجل ( 'اثنين' ) ;
أتصل مرة أخرى ( ) ;
} , 2000 ) ;
}
وظيفة الطباعة ثلاثة ( ) {
setTimeout ( وظيفة ( ) {
وحدة التحكم. سجل ( 'ثلاثة' ) ;
} , 3000 ) ;
}
وحدة التحكم. سجل ( 'بداية البرنامج' ) ;
printOne ( وظيفة ( ) {
printTwo ( وظيفة ( ) {
طباعة ثلاثة ( ) ;
} ) ;
} ) ;
وحدة التحكم. سجل ( 'نهاية البرنامج' ) ;
في هذا الكود أعلاه:
- تم الإعلان عن ثلاث وظائف لطباعة 'One' و'Two' و'Three'، ولكل وظيفة معلمة رد اتصال تسمح بالتنفيذ المتسلسل للتعليمات البرمجية.
- يتم تعيين المهلة باستخدام وظيفة setTimeout ويوجد بيان console.log للطباعة بعد تأخير محدد.
- تتم طباعة رسالتين 'بداية البرنامج' و'نهاية البرنامج' تشيران إلى بداية البرنامج ونهايته.
- يبدأ البرنامج بطباعة 'بدء البرنامج' وبعدها يتم تنفيذ الدالة printOne بتأخير 1 ثانية، ثم يتم تنفيذ الدالة printTwo بتأخير 2 ثانية، وأخيراً يتم تنفيذ الدالة printThree بتأخير 3 ثواني تأخير.
- لا ينتظر البرنامج تنفيذ التعليمات البرمجية غير المتزامنة داخل وظائف setTimeouts التي تسجل بيان 'نهاية البرنامج' قبل طباعة واحد واثنين وثلاثة.
انتاج |
قم بتشغيل الكود أعلاه عن طريق تنفيذ هذا الأمر في المحطة:
تطبيق العقدة. jsالآن سيظهر الإخراج في المحطة بشكل غير متزامن على النحو التالي:
الآن بعد أن أصبح لدينا فهم كامل للتنفيذ المتزامن وغير المتزامن، فلننتقل إلى ترسيخ مفهومنا لحلقة الحدث في Node.js.
Node.js: آلية حلقة الحدث
تتم إدارة تنفيذ كل من المهام المتزامنة وغير المتزامنة من خلال حلقة الأحداث في Node.js. ويتم استدعاء التنفيذ بمجرد إطلاق مشروع Node.js ونقل المهام المعقدة بسلاسة إلى النظام. وهذا يضمن أن المهام الأخرى يمكن أن تعمل بسلاسة على الموضوع الرئيسي.
شرح مرئي لحلقة الأحداث في Node.js
حلقة الحدث مستمرة وشبه لا نهائية في Node.js. يتم استدعاء حلقة الحدث عند بداية البرنامج النصي لرمز Node.js، وهي مسؤولة عن إجراء استدعاءات غير متزامنة لواجهة برمجة التطبيقات واستدعاء العمليات. ضع علامة () على جدولة الموقتات ثم تستأنف تنفيذ حلقة الحدث.
في Node.js، هناك خمسة أنواع رئيسية من قوائم الانتظار تتعامل مع عمليات الاسترجاعات:
- تعد 'قائمة انتظار المؤقت' المعروفة باسم الكومة الصغيرة مسؤولة عن معالجة عمليات الاسترجاعات المرتبطة بـ 'setTimeout' و'setInterval'.
- تتم معالجة عمليات الاسترجاعات للعمليات غير المتزامنة كما هو الحال في الوحدات النمطية 'fs' و'http' من خلال 'قائمة انتظار الإدخال/الإخراج'.
- يحتوي 'التحقق من قائمة الانتظار' على عمليات رد اتصال لوظيفة 'setImmediate' الفريدة لـ Node.
- تدير 'قائمة الانتظار المغلقة' عمليات الاسترجاعات المرتبطة بحدث إغلاق أي مهمة غير متزامنة.
- وأخيرًا، هناك قائمتان مختلفتان في قائمة انتظار 'المهام الصغيرة':
- تحتوي قائمة الانتظار 'nextTick' على عمليات الاسترجاعات المرتبطة بالوظيفة 'process.nextTick'.
- تتحكم قائمة الانتظار 'Promise' في عمليات الاسترجاعات المتعلقة بـ Promise الأصلي.
وظيفة حلقة الأحداث في Node.js
تعمل حلقة الحدث وفقًا لمتطلبات محددة تتحكم في ترتيب تنفيذ رد الاتصال. يتم إعطاء الأولوية لرمز Javascript المتزامن الخاص بالمستخدم في بداية العملية، لذلك تبدأ حلقة الحدث فقط عندما يتم مسح مكدس الاستدعاءات. يتبع تسلسل التنفيذ التالي نمطًا منظمًا:
يتم إعطاء الأولوية القصوى لعمليات الاسترجاعات في قائمة انتظار المهام الدقيقة ثم الانتقال لتنفيذ المهام في قائمة انتظار nextTick تليها المهام في قائمة انتظار الوعد. تتم بعد ذلك معالجة العمليات الموجودة في عمليات رد الاتصال بقائمة انتظار المؤقت، وبعد ذلك تتم إعادة زيارة قائمة انتظار المهام الدقيقة بعد كل رد اتصال للمؤقت. يتم بعد ذلك تنفيذ عمليات الاسترجاعات في قوائم انتظار الإدخال/الإخراج والفحص والإغلاق بنمط مماثل مع قائمة انتظار المهام الصغيرة التي تتم زيارتها بعد كل مرحلة.
تستمر الحلقة في التنفيذ إذا كان هناك المزيد من عمليات الاسترجاعات التي يجب معالجتها. عند انتهاء البرنامج النصي للتعليمات البرمجية أو عدم ترك أي رد اتصال للمعالجة، تنتهي حلقة الحدث بكفاءة.
الآن بعد أن فهمنا بعمق حلقة الأحداث، دعونا نلقي نظرة على ميزاتها.
ميزات حلقة الحدث في Node.js
الميزات الرئيسية هي:
- حلقة الحدث هي حلقة لا نهائية وتستمر في تنفيذ المهام بمجرد استلامها وتنتقل إلى وضع السكون في حالة عدم وجود مهام ولكنها تبدأ في العمل بمجرد استلام المهمة.
- يتم تنفيذ المهام الموجودة في قائمة انتظار الأحداث فقط عندما تكون المكدس فارغة، مما يعني عدم وجود عملية نشطة.
- يمكن استخدام عمليات الاسترجاعات والوعود في حلقة الحدث.
- نظرًا لأن حلقة الحدث تتبع مبدأ قائمة انتظار نوع البيانات المجردة، فإنها تنجز المهمة الأولى ثم تنتقل إلى المهمة التالية.
بعد الفهم الشامل لحلقة الحدث، ومنطق عمليات التنفيذ غير المتزامنة والمتزامنة، فإن فهم المراحل المختلفة قد يؤدي إلى ترسيخ مفاهيم حلقة الحدث.
مراحل حلقة حدث Node.js
كما ذكر أعلاه، حلقة الحدث شبه لا نهائية. لها مراحل عديدة ولكن يتم استخدام بعض المراحل للمعالجة الداخلية. هذه المراحل ليس لها أي تأثير على البرنامج النصي للتعليمات البرمجية.
تتبع حلقة الحدث وظيفة قائمة الانتظار وتنفذ المهمة وفقًا لمبدأ الدخول أولاً والخروج أولاً. سيتم التعامل مع الموقتات المجدولة بواسطة نظام التشغيل حتى تنتهي صلاحيتها. تتم بعد ذلك إضافة المؤقتات منتهية الصلاحية إلى قائمة انتظار رد الاتصال الخاصة بالمؤقتات.
تقوم حلقة الأحداث بتنفيذ المهام في قائمة انتظار المؤقت واحدة تلو الأخرى حتى لا يتبقى أي مهام أو تصل إلى الحد الأقصى لعدد المهام المسموح به. في الأقسام أدناه يتم شرح المراحل الأساسية لحلقات الأحداث.
مرحلة الموقتات
يوجد في Node.js واجهة برمجة تطبيقات مؤقتة يمكنها جدولة الوظائف التي سيتم تنفيذها في المستقبل. بعد مرور الوقت المخصص، سيتم تنفيذ رد الاتصال المؤقت بمجرد جدولته؛ ومع ذلك، قد يتم مواجهة تأخير إما من نهاية نظام التشغيل أو بسبب تنفيذ عمليات الاسترجاعات الأخرى.
تحتوي واجهة برمجة تطبيقات المؤقتات على ثلاث وظائف رئيسية:
- setTimeout
- setImmediate
- setInterval
الوظائف المذكورة أعلاه متزامنة. يقتصر نطاق مرحلة المؤقت في حلقة الحدث على وظائف setTimeout وsetInterval. بينما تتعامل وظيفة الاختيار مع وظيفة setImmediate.
دعونا نفكر في مثال بسيط لترسيخ الجزء النظري:
// application.jsوظيفة متأخرة ( ) {
وحدة التحكم. سجل ( 'يتم تنفيذ الوظيفة المؤجلة بعد انتهاء المهلة' ) ;
}
وحدة التحكم. سجل ( 'بداية البرنامج' ) ;
setTimeout ( وظيفة مؤجلة, 2000 ) ;
وحدة التحكم. سجل ( 'نهاية البرنامج' ) ;
في هذا الكود:
- يبدأ البرنامج بتسجيل عبارة 'بدء البرنامج' في الجهاز.
- ثم يتم استدعاء الوظيفة المؤجلة بمؤقت قدره 2 مللي ثانية، ولا يتوقف البرنامج النصي للكود ويواصل معالجة التأخير في الخلفية.
- العبارة 'يتم تسجيل نهاية البرنامج بعد العبارة الأولى.
- بعد تأخير قدره 2 مللي ثانية، يتم تسجيل البيان الموجود في الوظيفة المؤجلة إلى الجهاز.
انتاج |
سيظهر الناتج بالشكل :
يمكن ملاحظة أن الكود لم يتوقف حتى تتم معالجة الوظيفة المؤجلة ؛ يتحرك للأمام وبعد التأخير، تتم معالجة رد اتصال الوظيفة.
عمليات الاسترجاعات المعلقة
تتحقق حلقة الأحداث من الأحداث التي تحدث، مثل قراءة الملفات أو أنشطة الشبكة أو مهام الإدخال/الإخراج، في مرحلة الاستقصاء. من المهم معرفة أنه في Node.js، يتم التعامل مع بعض الأحداث فقط في مرحلة الاقتراع هذه. ومع ذلك، في التكرار اللاحق لحلقة الحدث، قد يتم تأجيل بعض الأحداث إلى المرحلة المعلقة. يعد هذا مفهومًا أساسيًا يجب أخذه في الاعتبار عند تحسين واستكشاف أخطاء كود Node.js وإصلاحها والتي تتضمن عمليات معقدة تعتمد على الأحداث.
من المهم أن نفهم أنه أثناء مرحلة انتظار عمليات رد الاتصال، تضيف حلقة الحدث أحداثًا مؤجلة إلى قائمة انتظار عمليات رد الاتصال المعلقة وتقوم بتنفيذها. تعالج هذه المرحلة أيضًا بعض أخطاء مقبس TCP التي أنشأها النظام، مثل أحداث خطأ ECONNREFUSED على أنظمة تشغيل معينة.
وفيما يلي مثال مذكور لترسيخ المفهوم:
// application.jsمقدار ثابت خ.س = يتطلب ( 'خس' ) ;
وظيفة readFileAsync ( مسار الملف، رد الاتصال ) {
خ. إقرا الملف ( './PromiseText.txt' , 'utf8' ، وظيفة ( خطأ، البيانات ) {
لو ( يخطئ ) {
وحدة التحكم. خطأ ( ` خطأ ملف القراءة : $ { يخطئ. رسالة } ` ) ;
} آخر {
وحدة التحكم. سجل ( ` ملف محتوى : $ { بيانات } ` ) ;
}
أتصل مرة أخرى ( ) ;
} ) ;
}
وحدة التحكم. سجل ( 'بداية البرنامج' ) ;
readFileAsync ( './PromiseText.txt' ، وظيفة ( ) {
وحدة التحكم. سجل ( 'تم تنفيذ رد الاتصال لقراءة الملف' ) ;
} ) ;
وحدة التحكم. سجل ( 'نهاية البرنامج' ) ;
في هذا الكود:
- يبدأ البرنامج بتسجيل عبارة 'بدء البرنامج' في الجهاز.
- يتم تعريف readFileAsync بشكل غير متزامن لقراءة محتوى الملف 'PromiseText.txt'. إنها وظيفة ذات معلمات تقوم بتنفيذ وظيفة رد الاتصال بعد قراءة الملف.
- يتم استدعاء الدالة readFileAsync لبدء عملية قراءة الملف.
- أثناء عملية قراءة الملف، لا يتوقف البرنامج؛ وبدلاً من ذلك، ينتقل إلى البيان التالي ويسجله في المحطة الطرفية 'نهاية البرنامج'.
- تتم معالجة الحدث غير المتزامن لقراءة الملف في الخلفية بواسطة حلقة الحدث.
- بعد قراءة الملف بشكل غير متزامن وتسجيل المحتوى في الجهاز، يقوم البرنامج بتسجيل محتوى الملف في الجهاز. بعد ذلك، يقوم بتسجيل الرسالة التالية 'تم تنفيذ رد اتصال قراءة الملف'.
- تعالج حلقة الحدث عمليات رد الاتصال المعلقة في المرحلة التالية.
انتاج |
نتيجة التنفيذ أعلاه هي:
الخمول، مرحلة التحضير في Node.js
يتم استخدام مرحلة الخمول للتعامل مع الوظائف الداخلية في Node.js لذا فهي ليست مرحلة قياسية. لا يؤثر على البرنامج النصي للتعليمات البرمجية. تشبه مرحلة الخمول فترة استراحة لحلقة الأحداث التي يتم خلالها إدارة المهام ذات الأولوية المنخفضة في الخلفية. مثال بسيط لفهم هذه المرحلة هو:
مقدار ثابت { عاطل } = يتطلب ( 'الخمول جي سي' ) ;عاطل. يتجاهل ( ) ;
في هذا الكود، يتم استخدام الوحدة النمطية 'idle-gc' التي تسمح بتجاهل مرحلة الخمول. يعمل هذا على معالجة المواقف التي تكون فيها حلقة الحدث مشغولة ولا يتم تنفيذ مهام الخلفية. لا يعتبر استخدام idle.ignore هو الأمثل لأنه يمكن أن يسبب مشكلات في الأداء.
مرحلة الاقتراع في Node.js
تعمل مرحلة الاستقصاء في Node.js على النحو التالي:
- يتعامل مع الأحداث في قائمة انتظار الاستقصاء وينفذ المهام المقابلة لها.
- فهو يقرر مقدار الوقت الذي يقضيه في الانتظار والتحقق من عمليات الإدخال/الإخراج في هذه العملية.
عندما تدخل حلقة الحدث مرحلة الاستقصاء بسبب عدم وجود مؤقت، سيتم تنفيذ إحدى المهام التالية:
- في مرحلة الاستقصاء من حلقة الحدث في Node.js، يتم وضع أحداث الإدخال/الإخراج المعلقة في قائمة الانتظار ثم يتم تنفيذها في إجراء تسلسلي باتباع مبدأ First In وFirst Out حتى تصبح قائمة الانتظار فارغة. أثناء عمليات عمليات رد الاتصال، تكون قوائم انتظار المهام الصغيرة والمهام التالية قيد التنفيذ أيضًا. وهذا يضمن السلاسة ويسمح بالتعامل مع عمليات الإدخال/الإخراج بشكل أكثر كفاءة وموثوقية.
- إذا كانت قائمة الانتظار فارغة ولم تتم جدولة البرنامج النصي بواسطة الدالة setImmediate()، فستنتهي حلقة الحدث وستنتقل إلى المرحلة التالية (التحقق). من ناحية أخرى، إذا تم تنفيذ جدولة البرنامج النصي بواسطة الدالة setImmediate()، فإن حلقة الحدث تسمح بإضافة ردود الاتصال إلى قائمة الانتظار التي سيتم تنفيذها بواسطتها.
من الأفضل توضيح ذلك بمثال رمز بسيط:
setTimeout ( ( ) => {وحدة التحكم. سجل ( 'اكتملت عملية المزامنة' ) ;
} , 2000 ) ;
وحدة التحكم. سجل ( 'يبدأ' ) ;
setImmediate ( ( ) => {
وحدة التحكم. سجل ( 'تم تنفيذ رد الاتصال setImmediate' ) ;
} ) ;
وحدة التحكم. سجل ( 'نهاية' ) ;
في هذا الكود:
- رسالتان 'ابدأ' و'انتهى' تشيران إلى بدء البرنامج وإنهائه.
- تقوم الدالة setTimeout() بتعيين وظيفة رد اتصال مع تأخير قدره 2 مللي ثانية وتسجل 'اكتملت عملية المزامنة' إلى الجهاز.
- تقوم الدالة setImmediate() بتسجيل رسالة 'تم تنفيذ رد الاتصال setImmediate' إلى الجهاز بعد تسجيل رسالة البدء في الجهاز.
انتاج |
سيُظهر الإخراج الرسائل بملاحظة دقيقة واحدة فقط أن 'اكتملت عملية المزامنة' تستغرق وقتًا ويتم طباعتها بعد رسالة 'الانتهاء':
مرحلة التحقق من Node.js
بعد تنفيذ مرحلة الاستقصاء، يتم تنفيذ عمليات الاسترجاعات في مرحلة التحقق. إذا تمت جدولة برنامج نصي للتعليمات البرمجية باستخدام وظيفة setImmediate() وكانت وظيفة الاستقصاء مجانية، فإن حلقة الحدث تعمل عن طريق الانتقال مباشرة إلى مرحلة التحقق بدلاً من البقاء خاملاً. الدالة setImmediate() هي مؤقت فريد يعمل خلال المراحل المختلفة لحلقة الحدث.
يتم استخدام واجهة برمجة تطبيقات libuv لتخطيط عمليات رد الاتصال بعد اكتمال تنفيذ مرحلة الاستقصاء. أثناء تنفيذ التعليمات البرمجية، تدخل حلقة الحدث في مرحلة الاستقصاء التي تنتظر فيها طلبات الاتصال الواردة. في حالة أخرى، إذا تمت جدولة رد الاتصال باستخدام الدالة setImmediate() وتم إنهاء مرحلة الاستقصاء دون أي نشاط، فسيتم الانتقال إلى مرحلة التحقق بدلاً من الانتظار. خذ بعين الاعتبار المثال التالي لفهم:
// application.jsوحدة التحكم. سجل ( 'يبدأ' ) ;
setImmediate ( ( ) => {
وحدة التحكم. سجل ( 'رد فوري' ) ;
} ) ;
وحدة التحكم. سجل ( 'نهاية' ) ;
في هذا الرمز يتم تسجيل ثلاث رسائل إلى الجهاز. تقوم الدالة setImmediate() أخيرًا بإرسال رد اتصال لتسجيل الرسالة ' رد اتصال فوري 'إلى المحطة.
انتاج |
سيظهر مخرج الكود أعلاه بالتسلسل التالي:
Node.js إغلاق عمليات الاسترجاعات
يستخدم Node.js مرحلة الإغلاق هذه لتشغيل عمليات رد الاتصال لإغلاق الأحداث وإنهاء تكرار حلقة الحدث. بعد إغلاق الاتصال، تعالج حلقة الحدث أحداث الإغلاق في هذه المرحلة. في هذه المرحلة من حلقة الحدث، يتم إنشاء 'nextTick()' والمهام الصغيرة ومعالجتها بشكل مشابه للمراحل الأخرى.
يتم استخدام الدالةprocess.exit لإنهاء حلقة الحدث في أي لحظة. ستتجاهل حلقة الحدث أي عمليات غير متزامنة معلقة وستنتهي عملية Node.js.
مثال بسيط يجب مراعاته هو:
// application.jsمقدار ثابت شبكة = يتطلب ( 'شبكة' ) ;
مقدار ثابت الخادم = شبكة. createServer ( ( قابس كهرباء ) => {
قابس كهرباء. على ( 'يغلق' , ( ) => {
وحدة التحكم. سجل ( 'المقبس مغلق' ) ;
} ) ;
قابس كهرباء. على ( 'بيانات' , ( بيانات ) => {
وحدة التحكم. سجل ( 'البيانات التي وردت:' ، بيانات. إلى سلسلة ( ) ) ;
} ) ;
} ) ;
الخادم. على ( 'يغلق' , ( ) => {
وحدة التحكم. سجل ( 'الخادم مغلق' ) ;
} ) ;
مقدار ثابت ميناء = 3000 ;
الخادم. يستمع ( ميناء، ( ) => {
وحدة التحكم. سجل ( `الخادم يستمع على المنفذ $ { ميناء } ` ) ;
} ) ;
setTimeout ( ( ) => {
وحدة التحكم. سجل ( 'إغلاق الخادم بعد 10 ثواني' ) ;
الخادم. يغلق ( ) ;
عملية. مخرج ( ) ;
} , 10000 ) ;
في هذا الكود:
- ' ثابت صافي = يتطلب ('صافي') 'يستورد الوحدة النمطية الصافية المطلوبة للتعامل مع خادم TCP و' خادم const = net.createServer((socket) => { ' يقوم بإنشاء مثيل خادم TCP جديد.
- ' المقبس.on('إغلاق', () => {... } 'يستمع إلى 'الإغلاق' على جميع المقابس. عندما يتم إغلاق اتصال المقبس، يتم تسجيل الرسالة 'Socket Closed' في الجهاز.
- ' المقبس.on('البيانات', (البيانات) => {} 'يتحقق من البيانات الواردة من جميع المقابس الفردية ويطبعها باستخدام وظيفة '.toString()'.
- ' server.on('إغلاق', () => {...} 'يتحقق من حدث 'الإغلاق' على الخادم نفسه، وعندما يتم إغلاق اتصال الخادم، فإنه يسجل رسالة 'الخادم مغلق' إلى المحطة.
- ' server.listen(port, () => {…} ' يستمع إلى الاتصالات الواردة على المنفذ.
- ' setTimeout(() => {…} ' يضبط مؤقتًا قدره 10 مللي ثانية لإغلاق الخادم.
وبهذا تنتهي المناقشة حول المراحل المختلفة لحلقة الحدث في Node.js. قبل القفز إلى الاستنتاج، دعونا نناقش شيئًا أخيرًا وهو كيفية الخروج من حلقة الحدث في Node.js.
الخروج من حلقة الأحداث في Node.js
حلقة الحدث في مرحلة التنفيذ طالما أن هناك بعض المهام في جميع قوائم انتظار مراحل حلقة الحدث. تنتهي حلقة الحدث بعد إطلاق مرحلة الخروج ويعود رد اتصال مستمع الخروج في حالة عدم وجود المزيد من المهام في قوائم الانتظار.
الطريقة الواضحة لإنهاء حلقة الحدث هي استخدام طريقة '.exit'. ستنتهي العمليات النشطة لـ Node.js على الفور بمجرد استدعاء وظيفةprocess.exit. سيتم إسقاط جميع الأحداث المجدولة والمعلقة:
عملية. على ( 'مخرج' , ( شفرة ) => {وحدة التحكم. سجل ( `الخروج برمز الخروج : $ { شفرة } ` ) ;
} ) ;
عملية. مخرج ( 1 ) ;
يمكن للمستخدمين الاستماع إلى وظيفة .exit. تجدر الإشارة إلى أن وظيفة '.exit' يجب أن تكون متزامنة حيث سيخرج برنامج Node.js بمجرد استماعه لهذا الحدث.
وبهذا تنتهي المناقشة حول حلقة الحدث. مقالة متعمقة تناولت جميع المفاهيم والمراحل والأمثلة المتعلقة بحلقة الحدث.
خاتمة
قبل فهم حلقة الحدث، يمكن أن تساعد نظرة عامة على المفاهيم المتزامنة وغير المتزامنة في فهم تدفق التعليمات البرمجية في حلقة الحدث. التنفيذ المتزامن يعني التنفيذ خطوة بخطوة بينما التنفيذ غير المتزامن يعني إيقاف بعض الخطوات دون انتظار اكتمالها. تتم مناقشة عمل حلقة الحدث مع جميع المراحل بالإضافة إلى الأمثلة المناسبة في المقالة.