حلقة حدث غير متزامن
غير متزامن
في JavaScript ، يعد عدم التزامن الأداة الرئيسية التي تعالج الطلبات بالتوازي مع تحميل صفحة الويب. الآن من المستحيل تخيل الإنترنت ، حيث سيتم إرسال جميع الطلبات إلى الخادم مع إعادة تحميل الصفحة.
يتم طلب أي بيانات من الخادم بشكل غير متزامن: يتم إرسال الطلب (XMLHttpRequest أو XHR) ، والرمز لا تنتظر عودته, الاستمرار في التنفيذ. عندما يستجيب الخادم ، يتم إخطار كائن XHR بذلك ويقوم بتشغيل وظيفة رد الاتصال التي تم تمريرها إليه قبل إرسال الطلب.
إذا كنت تستخدم أدوات اللغة بشكل صحيح , ثم تنفيذ الطلب الذي يحدث بشكل متتابع وفي خيط واحد لا يتدخل بأي شكل من الأشكال في استقبال الأحداث ورد الفعل عليها - شخص يعمل بهدوء مع الواجهة ، دون ملاحظة التأخيرات والأعطال والتجميد.
حلقة الحدث
جافا سكريبت Event loop
هو مدير مكالمات غير متزامن.
لجعل هذه العملية الصعبة تعمل بسلاسة ، تنفذ JavaScript آلية للتحكم في تسلسل تنفيذ التعليمات البرمجية. لأنها لغة ذات ترابط واحد , أصبح من الضروري "الإسفين" في سياق التنفيذ الحالي. هذه الآلية تسمى حلقة الحدث.
من الانجليزية، loop
يترجم كـ "حلقة" ، وهو ما يعكس المعنى تمامًا: نحن نتعامل مع قائمة انتظار الاسترجاع.
Event loop
ينظم تسلسل تنفيذ السياقات - المكدس. يتم إنشاؤه عندما يتم تشغيل حدث أو استدعاء وظيفة. يتم وضع الاستجابة للحدث في قائمة انتظار التنفيذ ، فيevent loop
,الذي ينفذ بالتسلسل ، مع كل حلقة ، الكود الذي يدخل فيه. في هذه الحالة ، يتم استدعاء الوظيفة المرتبطة بالحدث التالي بعد سياق التنفيذ الحالي.
في JavaScript ، يتم تشغيل قوائم انتظار التنفيذ المتزامن وغير المتزامن باستمرار. متزامن - stack
- تشكل قائمة انتظار وإعادة توجيهها إلى غير متزامن -event loop
- استدعاءات الوظائف التي سيتم تنفيذها بعد السياق القابل للتنفيذ المجدول حاليًا.
لكي تكون البيانات في حالة متسقة ، يجب إكمال كل وظيفة. ويرجع ذلك إلى الترابط الفردي لجافا سكريبت وبعض الميزات الأخرى ، مثل خصائص الإغلاق المميزة "للغات" الوظيفية للبرمجة. لذلك ، يتم تمثيل خيط واحد كقائمة انتظار لسياقات التنفيذ ، حيث تكون الوظائف التي مرت عبر حلقة الحدث "مثبتة".
وصف
JavaScript هي لغة ذات ترابط واحد: يمكن تشغيل مهمة واحدة فقط في كل مرة. هذه ليست مشكلة كبيرة في العادة ، لكن تخيل الآن أنك تقوم بمهمة تستغرق 30 ثانية ... نعم. أثناء هذه المهمة ، ننتظر 30 ثانية قبل أن يحدث أي شيء آخر (افتراضيًا ، يتم تشغيل JavaScript على سلسلة المتصفح الرئيسية ، لذلك ستنتظر واجهة المستخدم بأكملها) إنه عام 2021 الآن ، لا أحد يريد موقعًا بطيئًا وغبيًا.
لحسن الحظ ، يوفر لنا المتصفح بعض الوظائف التي لا توفرها JavaScript نفسها: واجهة برمجة تطبيقات الويب. والتي تتضمن DOM API و setTimeout وطلبات HTTP وما إلى ذلك. يمكن أن يساعدنا هذا في إنشاء سلوك غير متزامن غير معطل.
عندما نستدعي وظيفة ، تتم إضافتها إلى مكدس الاستدعاءات. مكدس الاستدعاءات هو جزء من محرك JS ، وهو مستعرض مستقل. هذه طريقة عرض كلاسيكية للمكدس ، أي first in
, last out
. عندما تعود دالة ، تنبثق من المكدس.
function great() {
return 'Hello'
}
function respond() {
return setTimeout(() => alert('Hey!'), 1000)
}
great()
respond()
تقوم وظيفة الاستجابة بإرجاع الدالة setTimeout. SetTimeout
يتم توفيره لنا من خلال Web-API
: يسمح لنا بتقسيم المهام دون حجب الخيط الرئيسي. ال Callback
وظيفة مررناها إلى setTimeout
وظيفة() => {return 'Hey'}
تمت إضافة وظيفة lambda إلى ملفWeb-API
. وفى الوقت نفسه، setTimeout
وresponde
من المكدس وإرجاع قيمها.
في Web-API
, يعمل الموقت حتى تنتظر الوسيطة الثانية التي مررناها إليها 1000 مللي ثانية. لا تتم إضافة رد الاتصال على الفور إلى مكدس الاستدعاءات ، ولكن يتم تمريره إلى ما يسمى قائمة الانتظار.
قد يكون هذا محيرًا: فهذا لا يعني أن ملف callback
تضاف وظيفة إلى مكدس الاستدعاءات (وبالتالي إرجاع قيمة) بعد 1000 مللي ثانية! تتم إضافته إلى قائمة الانتظار بعد 1000 مللي ثانية. ولكن في قائمة الانتظار هذه ، يجب أن تنتظر الوظيفة حتى يحين دورها.
الآن هذا هو الجزء الذي كنا ننتظره جميعًا ... حان الوقت لفعل حلقة الحدث شيئًا واحدًا: توصيل قائمة الانتظار بمكدس المكالمات! إذا كانت مكدس الاستدعاءات فارغًا ، أي إذا أعادت جميع الوظائف التي تم استدعاؤها سابقًا قيمها وتم إخراجها من المكدس ، فسيتم إضافة العنصر الأول في قائمة الانتظار إلى مكدس الاستدعاءات. في هذه الحالة ، لم يتم استدعاء أي وظائف أخرى ، مما يعني أن مكدس الاستدعاءات كان فارغًا بحلول الوقتcallback
كانت الوظيفة العنصر الأول في قائمة الانتظار.
يتم دفع رد الاتصال إلى مكدس المكالمات ، ويتم استدعاؤه وإعادته ، وإزالته من المجموعة.
من الممتع مشاهدتها ، لكن لا يمكنك استيعاب موضوع بالكامل دون العمل عليه مرارًا وتكرارًا. حاول معرفة ما يظهر في وحدة التحكم إذا قمنا بتشغيل ما يلي:
const foo = () => console.log('First')
const bar = () => setTimeout(() => console.log('Second'), 500)
const baz = () => console.log('Third')
bar()
foo()
baz()
دعونا نرى ما يحدث عندما نقوم بتشغيل هذا الرمز في المتصفح:
نحن نتصل bar
, الذي يعيد الsetTimeout
وظيفة.
الCallback
الذي مررنا إليه setTimeout
يضاف إلى Web API
, الsetTimeout
وbar
تنبثق وظائف من مكدس المكالمات.
في غضون ذلك ، يبدأ الموقت foo
يسمى والسجلات First
. foo
عائدات undefined
, baz
يسمى و callback
يضاف إلى قائمة الانتظار
baz
السجلات Third
. ترى حلقة الحدث أن callstack فارغ بعد عودة baz ، وبعد ذلك تتم إضافة رد الاتصال إلى مكدس الاستدعاءات.
Callback
السجلاتSecond
.
آمل أن يجعلك هذا تشعر بمزيد من الثقة معevent loop
!
لا تقلق إذا كان هذا لا يزال يبدو محيرًا ، فالشيء الأكثر أهمية هو فهم مصدر أخطاء معينة أو سلوك معين.
مشاكل؟
اكتب لDiscord محادثة.
أسئلة:
عدم التزامن هو:
- أداة تعرض سياق تنفيذ وظيفة من دفق متزامن
- أداة تنفذ التعليمات البرمجية سطرًا بسطر
- أداة تعالج الطلبات بالتوازي مع تحميل صفحات الويب
مدير الاتصال غير المتزامن:
stack
Event loop
JavaScript
يتم إجراء مكالمات الوظائف في:
- كومة
- حفنة من
- حلقة
الأداة التي تنفذ التعليمات البرمجية بتأخير ميلي ثانية:
delay
heap
setTimeout
لفهم مقدار ما تعلمته في هذا الدرس ، قم بإجراء الاختبار فيmobile application من مدرستنا في هذا الموضوع.
الروابط:
- Explaining how EventLoop works in JavaScript
- How to manage event loop in JavaScript
- Javascript reference
- Article: Explaining Event Loop in Javascript Using Rendering
- Article: JavaScript Visualized: Promises & Async / Await
المساهمون ✨
الشكر يعود إلى هؤلاء الأشخاص الرائعين(emoji key):
AlisaNasibullina | Dmitriy Vasilev 💵 | Resoner2005 🐛 🎨 |