๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

(JS) Event Loop์™€ ๋น„๋™๊ธฐ ๐Ÿ”

ยท ์•ฝ 7๋ถ„
์‹ฌ์™„

Single Threaded Language์ธ Javascript์—์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด Event Loop์™€ ํ•จ๊ป˜ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๊ธฐ์— ์•ž์„œ ๐Ÿ“โ€‹

Javascript๋Š” ์›น ๊ฐœ๋ฐœ์— ๋„๋ฆฌ ์‚ฌ์šฉ๋˜์ง€๋งŒ, ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ์ด๋Ÿฌํ•œ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด Javascript๊ฐ€ Event Loop๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค.

๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ž€? ๐Ÿค”โ€‹

์„ค๋ช…ํ•˜๊ธฐ์— ์•ž์„œ ์ฝ”๋“œ ์‹คํ–‰ ๋ฐฉ์‹์— ๋Œ€ํ•œ 2๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ์‹์ธ ๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ : ํ•œ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋‹ค์Œ ์ž‘์—…์„ ์‹œ์ž‘
  • ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ : ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์‹คํ–‰

๋ฐ์ดํ„ฐ fetching, ์œ ์ € input ์ฒ˜๋ฆฌ, DOM ์—…๋ฐ์ดํŠธ์™€ ๊ฐ™์€ ์ž‘์—…์— ์„œ๋กœ ๋‹ค๋ฅธ ์‹œ๊ฐ„์ด ์†Œ์š”๋  ์ˆ˜ ์žˆ๋Š” ์›น์„ ๊ฐœ๋ฐœํ•˜๋Š”๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. Javascript๋Š” ์ž‘์—… ์‹คํ–‰๊ณผ ์ฝœ๋ฐฑ์„ ๊ด€๋ฆฌํ•˜๋Š” Event Loop๋ฅผ ์‚ฌ์šฉํ•ด ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

Event Loop ์ž์„ธํžˆ ์ดํ•ดํ•˜๊ธฐ ๐Ÿ”โ€‹

Event Loop๋Š” Javascript ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์˜ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. Event Loop๋Š” ์ฝ”๋“œ ์‹คํ–‰, ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ, ์ฝœ๋ฐฑ์„ non-blocking ๋ฐฉ์‹์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Event Loop์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

Event Loop์˜ ๊ตฌ์„ฑ ์š”์†Œ
  1. Call Stack: Javascript ์—”์ง„์€ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์„ ์ž…์„ ์ถœ(LIFO) ์ˆœ์„œ๋กœ ์—ฌ๊ธฐ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœ๋  ๋•Œ ์Šคํƒ์— ์ถ”๊ฐ€๋˜๊ณ  ์™„๋ฃŒ๋˜๋ฉด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

  2. Callback Queue: "์ž‘์—… Queue" ๋˜๋Š” "๋ฉ”์‹œ์ง€ Queue"๋ผ๊ณ ๋„ ํ•˜๋ฉฐ, ์™„๋ฃŒ๋œ ๋น„๋™๊ธฐ ์ž‘์—… ์ฝœ๋ฐฑ์ด ์ €์žฅ๋˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. ์ฝœ๋ฐฑ์€ ์ถ”๊ฐ€๋œ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

  3. Web API: setTimeout, fetch, addEventListener์™€ ๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ € ์ œ๊ณต API๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Javascript ์—”์ง„๊ณผ๋Š” ๋ณ„๊ฐœ์ด์ง€๋งŒ Event Loop์™€ ๊ธด๋ฐ€ํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

  4. Microtask Queue: ์ด Queue๋Š” ํ”„๋กœ๋ฏธ์Šค ๋ฐ MutationObserver ์ฝœ๋ฐฑ ๊ฐ™์€ "Microtask"๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Microtask Queue๋Š” Callback Queue๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์œผ๋ฉฐ, Call Stack์˜ ๊ฐ ์ž‘์—… ์ดํ›„์— ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

Event Loop๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค:

Event Loop์˜ ์ž‘๋™ ๋ฐฉ์‹
  1. Javascript ์—”์ง„์ด Call Stack์—์„œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋น„๋™๊ธฐ ์ž‘์—…์€ ๊ฐ Web API๋กœ off-load ๋ฉ๋‹ˆ๋‹ค.
  3. ์™„๋ฃŒ๋œ ๋น„๋™๊ธฐ ์ž‘์—… ์ฝœ๋ฐฑ์ด Callback Queue์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
  4. Event Loop๋Š” Call Stack์ด ๋น„์›Œ์ง„ ํ›„ Microtask Queue๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  5. Event Loop๋Š” Callback Queue๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ๊ฐ ์ฝœ๋ฐฑ์„ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
1. Call Stack           2. Web APIs
---------- --------
| | ---Async---> | |
---------- --------
| | | |
---------- --------
| |
| |
v v
3. Microtask Queue 4. Callback Queue
--------------- -------------
| | <---- | |
--------------- -------------
| | | |
--------------- -------------

์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ํ†ตํ•ด Javascript ์—”์ง„์€ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ ์ž‘์—…์„ ๊ณ„์† ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Node.js์™€ ๋ธŒ๋ผ์šฐ์ €์˜ Event Loop ๐ŸŒโ€‹

Node.js์™€ ๋ธŒ๋ผ์šฐ์ € ๋ชจ๋‘ Event Loop๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ์ฝ”๋“œ ์‹คํ–‰์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ช‡ ๊ฐ€์ง€ ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค:

Node.js์™€ ๋ธŒ๋ผ์šฐ์ €์˜ Event Loop ์ฐจ์ด์ 
  1. Web API์™€ Timer: ๋ธŒ๋ผ์šฐ์ €๋Š” ์›น API ์„ธํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, Node.js๋Š” ์ž์ฒด API์™€ ํƒ€์ด๋จธ(setImmediate, process.nextTick ๋“ฑ)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์š” ์ฐจ์ด์ ์€ ๊ฐ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ API์ž…๋‹ˆ๋‹ค.

  2. Concurrency ๋ชจ๋ธ: ๋ธŒ๋ผ์šฐ์ €๋Š” ์›น ์›Œ์ปค API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Node.js๋Š” ๋น„์Šทํ•œ ๋™์‹œ์„ฑ์„ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์›Œ์ปค ์Šค๋ ˆ๋“œ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  3. Event-Driven ์•„ํ‚คํ…์ฒ˜: Node.js์™€ ๋ธŒ๋ผ์šฐ์ € ๋ชจ๋‘ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ์ˆ˜์‹ ํ•˜๋Š” ์ด๋ฒคํŠธ ์ฃผ๋„ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ด๋ฒคํŠธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์œ ์ € ์ƒํ˜ธ์ž‘์šฉ๊ณผ ๊ด€๋ จ์ด ์žˆ์œผ๋ฉฐ, Node.js์—์„œ๋Š” I/O ์ž‘์—…๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  4. Event Loop ๊ตฌํ˜„: ๋ธŒ๋ผ์šฐ์ €๋Š” HTML5 ์‚ฌ์–‘์„ ์‚ฌ์šฉํ•˜๋ฉฐ, Node.js๋Š” libuv ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์ž์ฒด ํฌ๋กœ์Šค ํ”Œ๋žซํผ Event Loop ๊ตฌํ˜„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ฐจ์ด์ ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  Event Loop์˜ ์ „๋ฐ˜์ ์ธ ๋™์ž‘ ๋ฐ ๊ธฐ๋Šฅ์€ ๋‘ ํ™˜๊ฒฝ์—์„œ ํฌ๊ฒŒ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

๋ธŒ๋ผ์šฐ์ €Node.js
Web API์™€ TimerWeb API์ž์ฒด API์™€ ํƒ€์ด๋จธ
Concurrency ๋ชจ๋ธWeb Workers APIWorker Threads module
Event-Driven ์•„ํ‚คํ…์ฒ˜User InterfaceI/O operations
Event Loop ๊ตฌํ˜„HTML5 specificationBuilt on the libuv library

๊ฒฐ๋ก  ๐Ÿโ€‹

Event Loop๋Š” Javascript ์–ธ์–ด ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์˜ ๊ธฐ๋ณธ์ ์ธ ๋ถ€๋ถ„์ด๊ธฐ ๋•Œ๋ฌธ์— Javascript ๊ฐœ๋ฐœ์ž์—๊ฒŒ Event Loop๋ฅผ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค. Event Loop์™€ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋งˆ์Šคํ„ฐํ•˜๋ฉด ๋›ฐ์–ด๋‚œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ˜์‘์„ฑ์ด ๋›ฐ์–ด๋‚˜๊ณ  ํšจ์œจ์ ์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.