λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ’» DEV/Javascript & NodeJS

[Javascript] 이벀트 루프 (Event Loop) λž€?

by vodkassi 2021. 9. 7.
728x90

✨  JS, Event Loop, Single Thread

NodeJs 의 single/multi thread μ—¬λΆ€λ₯Ό μ •λ¦¬ν•˜λ‹€λ³΄λ‹ˆ Js 의 Event Loop κ°œλ…μ„ 쑰금 더 ν™•μ‹€νžˆ μ•Œμ•„λ‘μ–΄μ•Όκ² λ‹€λŠ” 생각이 λ“€μ—ˆλ‹€. 

 

[NodeJS] NodeJS λŠ” Single Thread 일까? Multi Thread 일까?

✨ 고민이 μ‹œμž‘λœ 계기 JS 기초λ₯Ό ν•™μŠ΅ν•˜λ˜ λ‹Ήμ‹œμ—λŠ” μŠ€λ ˆλ“œμ™€ ν”„λ‘œμ„ΈμŠ€μ˜ κΈ°λ³Έ κ°œλ…μ„ ν•™μŠ΅ν•΄λ‘κΈ°λ§Œ ν•˜κ³ , ꡬ체적으둜 μ‚΄νŽ΄λ³΄μ§€ λͺ»ν–ˆμ—ˆλ‹€. μ›Ήκ°œλ°œ κ΅μœ‘κ³Όμ •μ΄ λλ‚˜κ°ˆ 무렡, μ‹€μ‹œκ°„ 쀌 κ°•μ˜μ—μ„œ

haeunyah.tistory.com

 

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ‹±κΈ€μŠ€λ ˆλ“œ 언어이닀. ν•˜μ§€λ§Œ 이전 κΈ€μ—μ„œλ„ λ³Ό 수 μžˆμ—ˆλ“―, λ©€ν‹°μŠ€λ ˆλ“œμ²˜λŸΌ λ™μ‹œμ— μ—¬λŸ¬ νƒœμŠ€ν¬μ˜ μž‘λ™μ΄ κ°€λŠ₯ν•˜λ‹€. 이 νŠΉμ§•μ€ λΈŒλΌμš°μ € λŸ°νƒ€μž„ ν™˜κ²½μ—μ„œλ„ λ™μΌν•˜λ‹€. 

 

μ™œμΌκΉŒ?

 

λ°”λ‘œ λŸ°νƒ€μž„ ν™˜κ²½ (Node, λΈŒλΌμš°μ €)의 이벀트 λ£¨ν”„λΌλŠ” μ‹œμŠ€ν…œ 덕뢄이닀. κ·Έλ ‡λ‹€λ©΄ 이벀트 루프가 무엇인지 ꡬ체적으둜 λ“€μ–΄κ°€λ³΄μž.

 

✨  Javascript ?

μš°μ„  MDN 이 μ •μ˜ν•˜λŠ” Javascript λŠ” λ‹€μŒκ³Ό κ°™λ‹€. 

JavaScript(JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions. While it is most well-known as the scripting language for Web pages, many non-browser environments also use it, such as Node.js, Apache CouchDB and Adobe Acrobat...

 

음. μ„€λͺ…이 λ‹€μ†Œ μ–΄λ ΅λ‹€λŠ” 감이 와, λ‹€λ₯Έ μ •μ˜λ₯Ό μ°Ύμ•„λ³΄κ²Œ λ˜μ—ˆλ‹€.

W3 Schools μ—μ„œλŠ” Javscript λ₯Ό κ°„λž΅νžˆ μ •μ˜ν•˜κ³  μžˆλ‹€.

 

JavaScript is the Programming Language for the Web.

 

이전보닀 쑰금 더 직관적이며 λͺ…ν™•ν•œ μ„€λͺ…이닀. "μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 웹을 μœ„ν•œ ν”„λ‘œκ·Έλž˜λ° 언어이닀."

 

μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ 웹에 νŠΉν™”λœ 언어라면, μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ μ›Ήμ—μ„œ μž‘λ™ν•  수 μžˆλ„λ‘ ν•˜λŠ” 일련의 μž₯μΉ˜λ“€μ΄ λΆ„λͺ… μ‘΄μž¬ν•  것이닀. 특히, 비동기 μž‘μ—…μ„ μœ„ν•œ μž₯μΉ˜κ°€ μ‘΄μž¬ν•  것이 λΆ„λͺ…ν•˜λ‹€. κ·Έ '일련의 μž₯치'κ°€ λ°”λ‘œ 이번 κΈ€μ—μ„œ λ‹€λ£¨κ²Œ 될 "Event Loop" 이닀. 

 

 

✨  Heap & Call Stack 

Javascript λŠ” κ·Έ 자체둜 μ‹€ν–‰λ˜μ§€ μ•ŠμœΌλ©°, Javascript λ₯Ό μ‹€ν–‰ν•˜κ²Œ ν•΄μ£ΌλŠ” νŠΉμ • 엔진이 ν•„μš”ν•˜λ‹€. κ·Έ 쀑 ν•˜λ‚˜κ°€ λ°”λ‘œ Chrome 에 λ‚΄μž₯된 μžλ°”μŠ€ν¬λ¦½νŠΈ μ‹€ν–‰ 엔진 V8 이닀. ν•˜μ§€λ§Œ 이보닀 깊게 λ“€μ–΄κ°€κΈ° 전에, Javascript 엔진인 V8은 크게 두 가지 κ΅¬μ„±μš”μ†Œλ‘œ λ‚˜λ‰œλ‹€λŠ” 사싀을 μ•Œμ•„μ•Ό ν•œλ‹€. 

 

Heap: 

- λ©”λͺ¨λ¦¬ 할당이 μ΄λ£¨μ–΄μ§€λŠ” 곡간

 

Call Stack: 

- μ‹€ν–‰λ˜μ–΄μ•Ό ν•˜λŠ” μž‘μ—…μ΄ μŒ“μ΄λŠ” 곡간 (console.log λ‚˜ μ‚¬μš©μž 지정 ν•¨μˆ˜) 

- Single-thread 이기 λ•Œλ¬Έμ—, ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ μž‘μ—…λ§Œ μˆ˜ν–‰ κ°€λŠ₯ν•˜λ‹€. 

 

 

 

 

πŸ“Œ μ—¬κΈ°μ„œ μ€‘μš”ν•œ 것은 Call Stack 의 μž‘λ™ 방식이닀. 

 

ν•¨μˆ˜ μ‹€ν–‰ call 이 μ΄λ£¨μ–΄μ§€λŠ” μˆœκ°„, ν•΄λ‹Ή ν•¨μˆ˜λŠ” call stack 에 λ‹΄κΈ°λ©°,

ν•¨μˆ˜ λ‚΄λΆ€μ˜ μˆœμ„œμ— λ”°λ₯Έ μ‹€ν–‰ μˆœμ„œλŒ€λ‘œ stack 에 계속 μž‘μ—…ν•  내역이 μŒ“μ΄κ²Œ λœλ‹€.

Stack 에 더 이상 담을 수 μžˆλŠ” call 이 μ—†λ‹€λ©΄, λ‚˜μ€‘μ— λ“€μ–΄μ˜¨ μž‘μ—…λΆ€ν„° 싀행이 λ˜μ–΄ Stack 을 λΉ μ Έλ‚˜κ°„λ‹€. (LIFO, μ„ μž…ν›„μΆœ 법칙) 

 

πŸ“Œ Stack 에 μžˆλŠ” μž‘μ—…μ΄ μ‹€ν–‰λ˜λŠ” μ‹œκ°„μ΄ 맀우 κΈΈλ‹€λ©΄?  이 ν˜„μƒμ΄ λ°”λ‘œ Blocking 이닀. 

 

Stack μ—μ„œλŠ” ν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” λ™μ•ˆ λ‹€λ₯Έ μž‘μ—…μœΌλ‘œ λ„˜μ–΄κ°ˆ 수 μ—†κΈ° 떄문에, νŠΉμ • μž‘μ—… μˆ˜ν–‰ μ‹œκ°„μ΄ 길어지면 λ‚˜λ¨Έμ§€ μž‘μ—…μ΄ 계속 "λŒ€κΈ°μ€‘" μƒνƒœμ— 머무λ₯Ό μˆ˜λ°–μ— μ—†λ‹€. μ΄λŸ¬ν•œ Blocking ν˜„μƒμ΄ 전체 μ›Ή λ Œλ”λ§ μ‹œμ— λ°œμƒν•˜κ²Œ λœλ‹€λ©΄ μœ μ €λŠ” νŠΉμ • μž‘μ—…μ΄ 끝날 λ•ŒκΉŒμ§€ λ²„νŠΌ 클릭을 ν•˜μ§€ λͺ»ν•˜κ±°λ‚˜, 계속 λ‘œλ”©μ°½μ„ λ°”λΌλ³΄κΈ°λ§Œ ν•΄μ•Ό ν•  μˆ˜λ„ μžˆλŠ” 것이닀. 

 

 

✨  Asynchronous (비동기) ν•¨μˆ˜μ™€ Event Loop

μœ„μ—μ„œ μ–ΈκΈ‰λœ Stack 의 기본적인 μž‘λ™ 흐름이 μ•ΌκΈ°ν•˜λŠ” λ¬Έμ œμ μ— λŒ€ν•œ κ°„λ‹¨ν•œ 해결책이 λ°”λ‘œ 비동기 ν•¨μˆ˜μ΄λ‹€. μž‘μ—… μ‹œκ°„μ΄ 였래 κ±Έλ¦¬λŠ” μ½”λ“œμ˜ 경우, λΉ„λ™κΈ°μ μœΌλ‘œ μ‹€ν–‰ν•˜λ„λ‘ μ„€μ •ν•΄ λ‘ μœΌλ‘œμ¨ Call Stack 이 μ•„λ‹Œ "λ‹€λ₯Έ μ˜μ—­" (μΆ”ν›„ μ„€λͺ… μ˜ˆμ •) μ—μ„œ μž‘μ—…μ„ ν•˜λ„λ‘ ν•˜λŠ” 것이닀. 이 경우, Blocking ν˜„μƒμ„ 방지할 뿐만 μ•„λ‹ˆλΌ μ½”λ“œ 싀행을 μ—¬λŸ¬ μΈ‘λ©΄μ—μ„œ 효율적으둜 ν•  수 있게 λœλ‹€. 

 

πŸ“Œ κ·Έλ ‡λ‹€λ©΄ 비동기 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λŠ” κ·Έ "λ‹€λ₯Έ μ˜μ—­"은 λŒ€μ²΄ 어디인가? 

 

μ—¬κΈ°μ„œ μ‘΄μž¬κ°μ„ λ“œλŸ¬λ‚΄λŠ” 것이 μ•„κΉŒ μ–ΈκΈ‰ν–ˆλ˜ 이벀트 루프이닀. 이벀트 λ£¨ν”„λŠ” λŸ°νƒ€μž„ ν™˜κ²½μ— λ‚΄μž₯된 μ—¬λŸ¬ μž₯μΉ˜λ“€κ³Ό μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진을 ν™œμš©ν•΄ 비동기 처리λ₯Ό ν•˜λŠ” μΌμ’…μ˜ λ™μž‘ μ‹œμŠ€ν…œμ΄λ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈ λŸ°νƒ€μž„μ€ ν•œ λ²ˆμ— ν•œ 가지 μž‘μ—…λ§Œ μˆ˜ν–‰ν•  수 μžˆμ§€λ§Œ, λΈŒλΌμš°μ €μ—μ„œ μ œκ³΅ν•˜λŠ” Web API 덕뢄에 비동기 ν•¨μˆ˜λ₯Ό λ³‘λ ¬μ μœΌλ‘œ μ²˜λ¦¬ν•  수 있게 λœλ‹€. (Nodeμ—μ„œλŠ” C++ API λ₯Ό 톡해 κ°€λŠ₯ν•˜λ‹€) 

 

πŸ“Œ  Event Loop 의 μ—­ν•  

 

Event Loop 의 역할은, Task Queue 와 Call Stack 을 κΎΈμ€€νžˆ κ°μ‹œν•˜λŠ” 것이닀. 

슀크립트 μ‹€ν–‰ 쀑 Stack 에 λ“€μ–΄μ˜¨ 동기 ν•¨μˆ˜λŠ” λ°”λ‘œ μ‹€ν–‰λ˜μ–΄ Stack 을 λΉ μ Έλ‚˜κ°€μ§€λ§Œ, 비동기 ν•¨μˆ˜λŠ” λΈŒλΌμš°μ €μ˜ Web ApI 둜 이동해 이 κ³΅κ°„μ—μ„œ μž‘μ—…μ„ μ§„ν–‰ν•œλ‹€. 그리고 비동기 ν•¨μˆ˜μ˜ μž‘업이 μ™„λ£Œλ˜λŠ” μˆœκ°„ λΈŒλΌμš°μ €μ˜ "Task Queue" λΌλŠ” κ³΅κ°„μœΌλ‘œ λ“€μ–΄κ°„λ‹€. 이벀트 λ£¨ν”„λŠ” Queue 와 Stack 을 계속 μ§€μΌœλ³΄λ‹€κ°€, Stack κ°€ λΉ„μ—ˆλ‹€λŠ” 것을 μ•Œμ•„μ°¨λ¦¬λŠ” μˆœκ°„, Task Queue 에 λ“€μ–΄μ˜¨ 첫 번째 μš”μ†ŒλΆ€ν„° μˆœμ„œλŒ€λ‘œ λ‹€μ‹œ Stack 에 올렀 ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜λ„λ‘ ν•œλ‹€. 

 

사싀 이 이미지 ν•œ μž₯이면 λͺ¨λ“  λ‚΄μš©μ„ λ‹€ νŒŒμ•…ν•  수 있긴 ν•˜λ‹€

 

μ΄λ ‡κ²Œ ν•˜μ—¬ JS μ—μ„œμ˜ 동기/비동기 ν•¨μˆ˜μ˜ μ‹€ν–‰ 원리, 그리고 이벀트 λ£¨ν”„μ˜ κ°œλ…κΉŒμ§€ κ΄„λͺ©ν•˜μ—¬ μ •λ¦¬λ˜μ—ˆλ‹€. 

 

 

✨  배운 λ‚΄μš©

  • Event Loop λŠ” .. 엔진이 μ•„λ‹ˆλ‹€.. κ·Έλ™μ•ˆ 잘λͺ»λœ ν‘œν˜„μ„ μ‚¬μš©ν•΄ μ™”λŠ”λ°, μ•žμœΌλ‘œλŠ” μš©μ–΄μ— 더 μ‹ κ²½ 써야겠닀. 
  • λΈŒλΌμš°μ € λŸ°νƒ€μž„κ³Ό Node 의 μž‘λ™ μ›λ¦¬λŠ” 기본적으둜 λ™μΌν•˜λ‹€. κ·Έ μ‹€ν–‰ ν™˜κ²½μ΄ ν™œμš©ν•˜λŠ” API λ˜λŠ” μ–Έμ–΄ 배경이 무엇이냐에 차이가 μžˆμ„ 뿐이닀. 

 

✨  참고자료

λŒ“κΈ€