رضا فتحی
رضا فتحی
خواندن ۲ دقیقه·۳ سال پیش

خیلی خیلی ساده راجع به Event Loop!

ایونت لوپ همان چیزی است که asynchronous programming را در جاواسکریپت ممکن میکند.

مراحل اجرای یک نرم افزارِ node را در نظر بگیریم… به این صورت است:
(فرض کنیم یک app ِ بسیار ساده با تنها یک thread (و یک event loop) داریم. به طور معمول بیش از یک thread -و نتیجتا بیش از یک event loop- خواهیم داشت)

  1. هنگام launch شدن یک thread ساخته میشود
  2. سپس event loop درون آن تِرِد initialized میشود
  3. تمامیِ code برنامه اجرا می شود (هنوز اجرای event loop آغاز نشده)
  4. سپس event loop اجرا می شود (و تا ابد ادامه دارد)


به هر iteration از event loop یک tick می گوییم که از 5 فاز(در واقع بیش از 5 فاز است) تشکیل شده:


گفتیم ابتدا قسمت های synchronous برنامه اجرا میشود و سپس(زمانی که stack از همه ی این قسمت های sync خالی شد) event loop اجرا میشود.

کارِ event loop (این 5 فاز) به طور ساده این است که هرگاه stack خالی بود اولین تسک از task queue را به stack بدهد.



برای درست کار کردن با event loop باید بدانیم که موارد زیر(عناصر async مان) کجای آن اند:

setTimeout ( callback, expTime ) setInterval ( callback, expTime ) setImmediate ( callback) process.nextTick( callback) promise // some promise instance
  • تابعِ callback ِ دو تابعِ setTimeout و setInterval بعد از اینکه زمانشان expire شد در اولین فرصت(همینطور که حلقه میچرخد) در فاز Timers اجرا میشود.
  • در مورد setImmediate تابعِ cb اش در فاز Check اجرا میشود (در واقع قبل از رفتن به tick ِ بعدی).
  • در event loop هر nextTick و promise یک میکروتسک محسوب میشود که اجرای آنها در بین فاز های مختلف هندل میشود. برای مثال در ابتدای ورود به یک tick ایونت لوپ بررسی میکند که آیا میکروتسکی وجود دارد و اگر وجود داشته باشد ابتدا آن اجرا میشود. به همین دلیل در نمونه کُدِ زیر ابتدا این دو لاگ میشوند:

خروجی به این صورت خواهد بود:

START the code ENDs, now EVENT_LOOP starts... promise 1 next tick 1 setImmediate 1 next tick 2 setTimeout 1 next tick 3 promise 2 setImmediate 2 setTimeout 3


یک جمله که خیلی شنیده میشود این است که "don't block the event loop". این مستقیماً به پرفورمنس برمیگردد. مثلا برای اینکه event loop برای انجام یک عملیات زمان بر، هندل کردن request ها - که در Polling phase انجام میشود - را معتل نکند(میدانیم ایونت لوپ سینگل ترد است) میتوانیم آن عملیات را توسط setImmediate که در Check phase و بعد از Polling اجرا شود، اجرا کنیم. اینگونه در هر tick اول request ها هندل شده و بعد آنکاره زمانبر انجام میشود..
روی هم رفته باید بدانیم چطور تسک ها را queue کنیم که پرفورمنس بهتری بگیریم!


چند رفرنس خوب در این باره:

Does Node.js have more than 1 event loop / task queue? - Quora

https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#:~:text=The%20event%20loop%20is%20what,operations%20executing%20in%20the%20background
http://docs.libuv.org/en/v1.x/design.html
https://runnable.com/blog/get-your-apps-to-the-poll-phase
https://stackoverflow.com/questions/46485392/poll-phase-in-nodejs-event-loop
https://youtu.be/ol56smloW2Q
https://youtu.be/8aGhZQkoFbQ



jsevent loop
شاید از این پست‌ها خوشتان بیاید