๐ ๋ค์ด๊ฐ๋ฉฐ
์๋ฐ์คํฌ๋ฆฝํธ์์ ์ด๋ฒคํธ ๋ฃจํ(Event Loop)๋ ๋ฌด์์ด๊ณ , ์ ์ค์ํ ๊ฐ๋ ์ผ๊น์?
์ฑ๊ธ ์ค๋ ๋(Single Thread)๋?
์๋ฐ์คํฌ๋ฆฝํธ๋ ์ฑ๊ธ ์ค๋ ๋ ๊ธฐ๋ฐ์ ์ธ์ด์ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ฑ๊ธ ์ค๋ ๋๋ ๋ฌด์์ผ๊น์?
์ฑ๊ธ ์ค๋ ๋๋ฅผ ์ดํดํ๊ธฐ ์ ์ ์ค๋ ๋๋ผ๋ ๊ฐ๋ ์ ๋จผ์ ์์์ผ ํฉ๋๋ค.
์ค๋ ๋๋ ํ๋ก์ธ์ค์ ์คํ ๋จ์์ ๋๋ค.
์ฆ, ์ผ์ ์ฒ๋ฆฌํ๋ ์์ ์์๊ณผ ๊ฐ์ ์ญํ ์ ํ๋ค๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.
์ฑ๊ธ ์ค๋ ๋๋ผ๋ ๊ฒ์ ๋ง ๊ทธ๋๋ก ์ค๋ ๋๊ฐ ํ๋๋ง ์กด์ฌ, ์ผ์ ์ฒ๋ฆฌํ๋ ์์ ์์์ด ํ ๋ช ๋ฐ์ ์๋ ์๊ธฐ์ ๋๋ค.
๋ธ๋กํน(Blocking)๊ณผ ๋ ผ๋ธ๋กํน(Non-blocking)
์ฐ๋ฆฌ์ ์์ ์์์ ํ ๋ช ์ด๋ผ์ ๋ชจ๋ ์ผ์ ํ ๋ฒ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
๋ง์ฝ ์ฐ๋ฆฌ๊ฐ ์ปดํจํฐ์๊ฒ ๋งก๊ธด ์ผ ์ค ํ๋๊ฐ ๋๋ฌด ์ค๋ ๊ฑธ๋ฆฐ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
๊ทธ๋ผ ๊ธด ์์
์ด ์๋ฃ๋ ๋๊น์ง ๋ค๋ฅธ ๋ชจ๋ ์์
๋ค์ด ๋ฉ์ถฐ์๋ค๊ฐ ํด๋น ์์
์ด ๋๋ ํ์ ๋ค์ ์งํ์ด ๋ ๊ฒ์
๋๋ค.
์ด๋ฌํ ๊ฒฝ์ฐ๋ฅผ ๋ฐ๋ก ๋ธ๋กํน์ด๋ผ๊ณ ํฉ๋๋ค.
ํ์ง๋ง ์ฐ๋ฆฌ๋ ์น์์ ํ์ผ๋ ๋ค์ด๋ก๋ํ๋ฉด์ ์น ์ํ๋ ํ๊ณ ๋์์๋ ๋ณด๊ณ ์ฌ๋ฌ ๊ฐ์ง ์ผ์ ํ ์ ์์ต๋๋ค.
์ด๊ฑด ๋ฐ๋ก ๋ ผ๋ธ๋กํน ๋ฐฉ์ ๋๋ฌธ์ ๋๋ค.
๋ ผ๋ธ๋กํน ๋ฐฉ์์์๋ ๊ธด ์์ ์ด ์งํ๋๋ ๋์์๋ ๋ค๋ฅธ ์์ ๋ค์ด ๊ณ์ ์งํ๋ ์ ์์ต๋๋ค.
์ด๋ฒคํธ ๋ฃจํ(Event Loop)์ ์กด์ฌ
์ฌ๊ธฐ์ ์ด๋ฒคํธ ๋ฃจํ์ ์ญํ ์ด ์ค์ํด์ง๋๋ค.
๋ ผ๋ธ๋กํน ๋ฐฉ์์์ ํ์ํ ๊ฒ์ฒ๋ผ, ์ด๋ฒคํธ ๋ฃจํ๋ ๊ธด ์์ ์ ํ๊ณ ์๋ ๋์ ์งง์ ์์ ๋ค๋ ๊ฐ์ด ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ฆ, ์ด๋ฒคํธ ๋ฃจํ๋ ์ฐ๋ฆฌ์ ์์ ์์์๊ฒ ์ด๋ค ์์ ๋ถํฐ ์์ํ๊ณ ์ธ์ ๋ค์ ์์ ์ผ๋ก ๋์ด๊ฐ์ง ์๋ ค์ฃผ๋ ์ญํ ์ ํ๊ณ ์์ต๋๋ค.
๊ทธ๋์ ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ฑ๊ธ ์ค๋ ๋ ์ธ์ด์์๋ ๋ถ๊ตฌํ๊ณ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ํตํด ๋ ผ๋ธ๋กํน ๋ฐฉ์์ ๋น๋๊ธฐ์ ์ธ ๋์์ฑ ์ธ์ด๋ก ๋์ํ ์ ์์ต๋๋ค.
์ด๋ฒคํธ ๋ฃจํ(Event Loop)์ ๊ตฌ์กฐ
์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ๊ฐ์ง๊ณ ์๋ ๋ถ๋ถ์ ๋ฉ๋ชจ๋ฆฌ ํ(Memory Heap)๊ณผ ์ฝ ์คํ(Call Stack)์ด ์์ต๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ํ(Memory Heap): ๋ฉ๋ชจ๋ฆฌ ํ์ ์ปดํจํฐ๊ฐ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ๊ณณ์ ๋๋ค. ์ฆ, ์๋ฐ์คํฌ๋ฆฝํธ ๊ด์ ์์ ๋ณด๋ฉด ์ฐ๋ฆฌ๊ฐ ๋ง๋๋ ๊ฐ์ฒด, ๋ฐฐ์ด, ํจ์ ๋ฑ์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ ๊ณต๊ฐ์ ๋๋ค.
- ์ฝ ์คํ(Call Stack): ์ฝ ์คํ์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ด์ ์์ ๋ดค์ ๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ํ ์ผ ๋ชฉ๋ก์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค. ํจ์๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด ํด๋น ํจ์์ ์ ๋ณด๊ฐ ์ฝ ์คํ์ ์์ด๊ฒ ๋๊ณ , ๋จผ์ ๋ค์ด๊ฐ ๊ฒ์ด ๋ง์ง๋ง์ ๋์ค๋ FILO(First In Last Out) ๊ตฌ์กฐ์ ๋๋ค.
์น API(Web APIs)์ ์ฝ๋ฐฑ ํ(Callback Queue)๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง ์ธ๋ถ์์ ๊ด๋ฆฌ๋๋ฉฐ, ์ฃผ๋ก ๋ธ๋ผ์ฐ์ ๋ Node.js์ ๊ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฐํ์ ํ๊ฒฝ์์ ์ ๊ณต๋ฉ๋๋ค.
- ์น API(Web APIs) : ์น API๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์ ๊ณตํ๋ ๋ค์ํ ๊ธฐ๋ฅ๋ค์ ์๋ฏธํฉ๋๋ค. ์๋ฅผ ๋ค์ด, HTTP ์์ฒญ, setTimeout ๋ฑ์ ๊ธฐ๋ฅ๋ค์ด ํฌํจ๋ฉ๋๋ค. ์ด๋ฐ ์์ ๋ค์ ์ฃผ๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌ๊ฐ ๋๋ฏ๋ก ์๋ฃ ์์ ์ ์ ํํ ์ ์ ์์ต๋๋ค.
- ์ฝ๋ฐฑ ํ(Callback Queue): ์ฝ๋ฐฑ ํ๋ ๋น๋๊ธฐ ์์ (์: setTimeout, HTTP ์์ฒญ)์ ๊ฒฐ๊ณผ๋ ๋์ค์ ์คํ๋์ด์ผ ํ๋ ์์ ๋ค์ด ๋๊ธฐํ๋ ๊ณต๊ฐ์ ๋๋ค. ๋จผ์ ๋ค์ด๊ฐ ์์ ์ด ๋จผ์ ๋๊ฐ๋ FIFO(First In First Out) ๊ตฌ์กฐ์ ๋๋ค. ์ฌ๊ธฐ์ ์๋ ์ฝ๋ฐฑ ํจ์๋ค์ ์ฝ์คํ์ด ๋น์ด์ก์ ๋ ๋จผ์ ๋๊ธฐ์ด์ ๋ค์ด์จ ์์๋๋ก ์ํ๋ฉ๋๋ค.
ํ์ง๋ง ๋จ์ํ ๋น๋๊ธฐ ํจ์๊ฐ ์ฝ๋ฐฑ ํ์ ์์ด๋ ๊ฒ์ ์๋๋๋ค.
์ฝ๋ฐฑ ํ์๋ ์ธ ๊ฐ์ง ์ข ๋ฅ๊ฐ ์์ต๋๋ค.
- ํ์คํฌ ํ(Task Queue): ์ผ๋ฐ์ ์ผ๋ก ๋งคํฌ๋ก ํ์คํฌ(Macrotask Queue)๋ผ๊ณ ๋ ๋ถ๋ฆ ๋๋ค. setTimeout, setInterval ๋ฑ์ ๋น๋๊ธฐ ์์ ์ด ์ด๊ณณ์ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
- ๋ง์ดํฌ๋กํ์คํฌ ํ(Microtask Queue): ํ๋ก๋ฏธ์ค(Promise)์ ์ฝ๋ฐฑ ํจ์๋ async / await๊ณผ ๊ฐ์ ์ฝ๋๊ฐ ์ด๊ณณ์ ๋ค์ด๊ฐ๋๋ค.
- ์ ๋๋ฉ์ด์ ํ๋ ์(Animation Frames): ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ํ๋ฉด์ ์ ๋ฐ์ดํธํ๋ ์์ ๋ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค. requestAnimationFrames๊ณผ ๊ฐ์ ์ฝ๋๊ฐ ์ฌ๊ธฐ์ ํด๋น๋ฉ๋๋ค.
๋ง์ดํฌ๋กํ์คํฌ ํ(Microtask Queue) > ์ ๋๋ฉ์ด์ ํ๋ ์(Animation Frames) > ํ์คํฌ ํ(Task Queue) ์์ผ๋ก Microtask Queue๊ฐ ๊ฐ์ฅ ๋จผ์ ์คํ๋๊ณ Task Queue๊ฐ ๊ฐ์ฅ ๋ฆ๊ฒ ์คํ๋๋ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋์ค์ ์คํ๋์ด์ผ ํ๋ ์์ ๋ค์ด ์ด๋ป๊ฒ ์ค์ ๋ก ์คํ๋ ๊น์?
๋ฐ๋ก ์ด๋ฒคํธ ๋ฃจํ(Event Loop)๊ฐ ๊ทธ ์ญํ ์ ๋ด๋นํฉ๋๋ค.
์ด๋ฒคํธ ๋ฃจํ๋ ์ฝ ์คํ๊ณผ ์ฝ๋ฐฑ ํ๋ฅผ ์ง์์ ์ผ๋ก ํ์ธํ๋ฉฐ, ์ฝ ์คํ์ด ๋น์ด์์ผ๋ฉด ์ฝ๋ฐฑ ํ์์ ๊ฐ์ฅ ์ค๋๋ ์์ (FIFO)์ ๊บผ๋ด์ ์ฝ ์คํ์ผ๋ก ์ฎ๊น๋๋ค.
// ์ด๋ฒคํธ ๋ฃจํ์ ๋์์ ๋ํ๋ด๋ ๊ฐ์์ ์ฝ๋
while(queue.waitForMessage()){ // ํ์ ๋ฉ์์ง๊ฐ ์์ ๋๊น์ง ๋๊ธฐ
queue.processNextMessage(); // ๊ฐ์ฅ ์ค๋๋ ๋ฉ์์ง๋ฅผ ํ์์ ๊บผ๋ด์ ํธ์ถ ์คํ์ผ๋ก ์ฎ๊น
}
์ ์ฝ๋๋ ์ด๋ฒคํธ ๋ฃจํ์ ๋์์ ๊ฐ๋ตํ๊ฒ ํํํ ์ฝ๋์ ๋๋ค.
์ด๋ฒคํธ ๋ฃจํ(Event Loop)์ ๋์ ๊ณผ์
๋จผ์ ์ด๋ฒคํธ ๋ฃจํ์ ๋์ ๋ฐฉ์์ ๋ํด์ ์ค๋ช ํ๊ณ ์์ ๋ค๊ณผ ํจ๊ป ์ค๋ช ํ๊ฒ ์ต๋๋ค.
์ด๋ฒคํธ ๋ฃจํ์ ๋์ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์ฝ ์คํ(Call Stack) ํ์ธ: ์ด๋ฒคํธ ๋ฃจํ๋ ๋จผ์ ํ์ฌ ์ฝ ์คํ์ด ๋น์ด ์๋์ง ํ์ธํฉ๋๋ค. ๋ง์ฝ ์ฝ ์คํ์ ์์ง ์ฒ๋ฆฌ๋์ง ์์ ํจ์๊ฐ ์๋ค๋ฉด, ํด๋น ํจ์๊ฐ ์์ ํ ์คํ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค.
- ์ฝ๋ฐฑ ํ(Callback Queue) ํ์ธ: ๋ง์ฝ ์ฝ ์คํ์ด ๋น์ด ์๋ค๋ฉด, ์ด์ ์ฝ๋ฐฑ ํ๋ฅผ ํ์ธํฉ๋๋ค. ์ฝ๋ฐฑ ํ์๋ ์น API ๋ฑ์์ ์์ฑ๋ ์ฝ๋ฐฑ ํจ์๋ค์ด ๋๊ธฐํฉ๋๋ค.
- ํจ์ ์ด๋: ์ฝ๋ฐฑ ํ์์ ๊ฐ์ฅ ์ค๋๋ ํจ์๋ฅผ ๊บผ๋ด์ ์ฝ ์คํ์ผ๋ก ์ฎ๊น๋๋ค.
- ํจ์ ์คํ: ์ด์ ํด๋น ํจ์๊ฐ ์ฝ ์คํ์์ ์คํ๋๊ณ ์คํ์ด ๋๋๋ฉด ์ฝ ์คํ์์ ๋น ์ ธ๋๊ฐ๊ฒ ๋ฉ๋๋ค.
- ์ ๊ณผ์ ๋ค์ ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋ ๋๊น์ง ๋ฐ๋ณตํฉ๋๋ค.
์ด๋ฒคํธ ๋ฃจํ์ ๋์ ๊ณผ์ ์ GIF๋ก ์์ฃผ ์ฝ๊ฒ ์ดํดํ ์ ์๋๋ก ์ ๋ฆฌํด ๋์ ๋ถ(Lydia Hallie)์ด ๊ณ์ ์ ํด๋น ์ด๋ฏธ์ง๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ค๋ช ํ๊ฒ ์ต๋๋ค.
์ฒซ ๋ฒ์งธ ์ฝ๋ ๋ถ์ (setTimeout๊ณผ ์ฝ๋ฐฑ ํ)
๊ทธ๋ผ ์ด์ ์์ ์ด๋ฏธ์ง ๋ฐ ๋น๋๊ธฐ ์ฝ๋์ ํจ๊ป ํ์ธํด๋ณผ๊น์?
function greet() {
return 'Hello!';
}
function respond() {
return setTimeout(() => {
return 'Hey!';
}, 1000);
}
greet();
respond();
์ ์ฝ๋์ ๋์ ๊ณผ์ ์ ์ด๋ป๊ฒ ๋ ๊น์?
๋จผ์ greet ํจ์๋ฅผ ๋ง๋์ ํธ์ถํ๊ฒ ๋ฉ๋๋ค.
์ฝ ์คํ์ ์คํ ์ค์ธ ํจ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ฝ ์คํ์ greet ํจ์๋ฅผ ๋ฃ์ด์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฐ๋ก ์คํ๋์ด "Hello!"๋ฅผ ์ถ๋ ฅํ๊ณ ์ฝ ์คํ์์ ์ฌ๋ผ์ง๊ฒ ๋ฉ๋๋ค.
๋ค์์ผ๋ก respond ํจ์๋ฅผ ๋ง๋์ ํธ์ถํฉ๋๋ค.
respond ํจ์๋ Web API๊ฐ ์ ๊ณตํ๋ setTimeout ํจ์๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ์์ ์ ์ง์ฐ์ํฌ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ๊ฐ ์์์ ์ด๋ฒคํธ ๋ฃจํ์ ์ค์์ฑ์ ๋ํด์ ์์๋ดค๋ฏ์ด ๋ง์ฝ setTimeout๊ณผ ๊ฐ์ ํจ์๊ฐ ๋ฐ๋ก ์ฝ ์คํ์ ๋ค์ด๊ฐ๋ค๋ฉด, ๊ทธ ํจ์๊ฐ ์์ ํ ์คํ๋ ๋๊น์ง ์ฆ, ํ์ด๋จธ๊ฐ ๋ง๋ฃ๋ ๋๊น์ง ๋ค๋ฅธ ๋ชจ๋ ์์ ๋ค์ ๋๊ธฐ ์ํ(Blocking)์ ๋์ด๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ผ์ setTimeout๊ณผ ๊ฐ์ ๋น๋๊ธฐ ํจ์๋ค์ ํธ์ถ๋๋ฉด ์น API๋ก ์ ๋ฌ๋ฉ๋๋ค.
setTimeout ํจ์์ respond ํจ์๋ ์ฝ ์คํ์์ ๋น ์ ธ๋์ค๋ฉด์ ๊ฐ์ ๋ฐํํ๊ฒ ๋๊ณ setTimeout์ ์ ๋ฌํ ์ฝ๋ฐฑ ํจ์๋ ๋ฐ๋ก ๋น ์ ธ๋์ ์น API๋ก ์ด๋ํ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์น API์์ setTimeout ํจ์์ ๋ ๋ฒ์งธ ์ธ์์๋ 1000ms(1์ด)๋งํผ ์คํ๋ฉ๋๋ค.
1000ms๋์ ์คํ์ด ๋๋ ํ ๋ฐ๋ก ์ฝ ์คํ์ผ๋ก ๋ค์ด๊ฐ๋ ๊ฒ์ด ์๋ ์ฝ๋ฐฑ ํ๋ก ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
์์ธํ๊ฒ๋ ํ์คํฌ ํ(Task Queue)๋ก ๋ค์ด๊ฐ ๊ฒ์ ๋๋ค.
์ด์ ์ด๋ฒคํธ ๋ฃจํ๊ฐ ์ฝ ์คํ์ด ๋น์ด์๋์ง ํ์ธ ํ, ์ฝ๋ฐฑ ํ์ ์๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฝ ์คํ์ ์ถ๊ฐํฉ๋๋ค.
์ฝ๋ฐฑ ํจ์๋ ์ฝ ์คํ์ ์ถ๊ฐ๋๊ณ , ํธ์ถ๋๊ณ , ๊ฐ์ ๋ฐํํ ๋ค์ ์ฝ ์คํ์์ ๋น ์ ธ๋๊ฐ๊ฒ ๋ฉ๋๋ค.
๋ ๋ฒ์งธ ์ฝ๋ ๋ถ์ (setTimeout, Promise, Macrotask Queue, Microtask Queue)
console.log('Start!');
setTimeout(() => {
console.log('Timeout!');
}, 0);
Promise.resolve('Promise!').then(res => console.log(res));
console.log('End!');
๊ทธ๋ผ ์์ ๊ฐ์ ์ฝ๋๋ ์คํ์ด ์ด๋ป๊ฒ ๋ ๊น์?
์์์ ์ค๋ช ํ๋ฏ์ด ๋น๋๊ธฐ ํจ์๋ผ๊ณ ๋ชจ๋ ๊ฐ์ ์ฝ๋ฐฑ ํ์ ์ถ๊ฐ๋๋ ๊ฒ์ด ์๋๊ณ ์ฐ์ ์์๊ฐ ์๋ค๊ณ ์ค๋ช ํ์ต๋๋ค.
๋จผ์ console.log๋ฅผ ๋ง๋๊ฒ ๋๊ณ ์ฝ ์คํ์ ์ถ๊ฐ๋ ํ "Start!"๋ผ๋ ๊ฐ์ด ์ถ๋ ฅ๋ ๋ค์ ์ฝ ์คํ์์ ๋น ์ ธ๋๊ฐ๋๋ค.
๋ค์ ์ค์์ ๋ฐ๋ก setTimeout ํจ์๋ฅผ ๋ง๋๊ฒ ๋ฉ๋๋ค.
setTimeout ๋ด๋ถ์ ์ฝ๋ฐฑ ํจ์๋ ์น API๋ก ๋์ด๊ฐ๋๋ค.
์ธ์๋ก 0์ ์ฃผ์์ง๋ง ๋น๋๊ธฐ ํจ์์ ์ฝ๋ฐฑ ํจ์๋ก ๋๊ฒจ๋ฐ์๊ธฐ ๋๋ฌธ์ ๋งคํฌ๋กํ์คํฌ ํ(Macro Queue)์ ์ถ๊ฐ๋ฉ๋๋ค.
๋ค์ ์ค์์ ๋ฐ๋ก ํ๋ก๋ฏธ์ค(Promise)๋ฅผ ๋ง๋๊ฒ ๋ฉ๋๋ค.
Promise.resolve๊ฐ ์ฝ ์คํ์ ์ถ๊ฐ๋ ํ ์ฝ๋ฐฑ ํจ์๊ฐ ๋ง์ดํฌ๋กํ์คํฌ ํ(Microtask Queue)์ ์ถ๊ฐ๋ฉ๋๋ค.
Promise.resolve๋ ๋น ์ ธ๋์ค๊ฒ ๋ฉ๋๋ค.
console.log๋ฅผ ๋ง๋ ํ ์ฝ ์คํ์ ์ถ๊ฐ๋๊ณ "End!"๋ฅผ ์ถ๋ ฅํ๊ณ ์ฝ ์คํ์์ ๋น ์ ธ๋์ต๋๋ค.
์ด์ ์ฝ ์คํ์ด ๋น์ด์๊ธฐ ๋๋ฌธ์ ๋ง์ดํฌ๋กํ์คํฌ ํ์ ๋๊ธฐ ์ค์ธ ์์ ์ด ์๋์ง ํ์ธ ํ ์ฝ ์คํ์ ์ถ๊ฐํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ Promise์ resolve ๊ฐ์ธ console.log๋ฅผ ์ถ๋ ฅํ๊ฒ ๋ฉ๋๋ค.
์ด์ ๋ค์ ๋ง์ดํฌ๋กํ์คํฌ ํ์ ๋๊ธฐ ์ค์ธ ์์ ์ด ์๋์ง ํ์ธํฉ๋๋ค.
๋๊ธฐ ์ค์ธ ์์ ์ด ์์ผ๋ ์ด์ ๋งคํฌ๋กํ์คํฌ ํ(Macrotask Queue)๋ฅผ ํ์ธํ ์ฐจ๋ก์ ๋๋ค.
๋งคํฌ๋กํ์คํฌ ํ์์ ๋๊ธฐ ์ค์ด์๋ setTimeout์ ์ฝ๋ฐฑ ํจ์์ธ console.log("Timeout")์ ์ฝ ์คํ์ ์ถ๊ฐํ ๋ค ์ถ๋ ฅํ๊ณ ์ฝ ์คํ์ฃ ๋น ์ ธ๋์ค๊ฒ ๋ฉ๋๋ค.
์ธ ๋ฒ์งธ ์ฝ๋ ๋ถ์ (async / await)
ES8์ ์ ์ฉ๋ async / await ๋ฌธ๋ฒ์ผ๋ก Promise๋ฅผ ์ฝ๊ฒ ๋ค๋ฃฐ ์ ์์ต๋๋ค.
asyncํค์๋๋ก Promise๋ฅผ ๋ฐํํ๋ await ๋น๋ํค ํจ์ ์ฝ๋ ์์ ๋ฅผ ๋ง์ง๋ง์ผ๋ก ์ดํด๋ณด๊ณ ๋ง๋ฌด๋ฆฌํ๊ฒ ์ต๋๋ค.
const one = () => Promise.resolve('One!');
async function myFunc() {
console.log('In function!');
const res = await one();
console.log(res);
}
console.log('Before function!');
myFunc();
console.log('After function!');
์ ์ฝ๋์ ์คํ ๊ฒฐ๊ณผ์ ๊ณผ์ ์ ์ด๋ป๊ฒ ๋ ๊น์?
๋จผ์ console.log๊ฐ ์ฝ ์คํ์ ์ถ๊ฐ๋ ํ "Before function!"์ด ์ถ๋ ฅ๋ฉ๋๋ค.
๋ค์์ผ๋ก myFunc ํจ์๊ฐ ํธ์ถ๋์ด ์ฝ ์คํ์ ์ถ๊ฐ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ myFunc์ ์ฒซ ๋ฒ์งธ ์ค์์ console.log๊ฐ ์ฝ ์คํ์ ์ถ๊ฐ๋ ํ "In function!"์ ์ถ๋ ฅํ ํ ์ฝ ์คํ์์ ๋น ์ ธ๋์ต๋๋ค.
๋ค์์ผ๋ก one ํจ์๋ Promise๋ฅผ ๋ฆฌํดํ๊ธฐ ์ด์ ์ ํจ์์ ๋๋ค.
๊ทธ๋์ one ํจ์๋ฅผ ์ฝ ์คํ์ ์ถ๊ฐํฉ๋๋ค.
one ํจ์๋ ์ฑ๊ณต๋ Promise (resolve)๋ฅผ ๋ฐํํฉ๋๋ค.
๊ฒฐ๊ตญ one ํจ์๋ ์คํ์ด ์๋ฃ๋์๊ธฐ ๋๋ฌธ์ ์ฝ ์คํ์์ ๋น ์ ธ๋๊ฐ๊ฒ ๋ฉ๋๋ค.
ํ์ง๋ง one ํจ์ ์์ await ํค์๋๊ฐ ๋ถ์ด์๊ธฐ ๋๋ฌธ์ ํด๋น ํจ์(myFunc)๋ ์ผ์ ์ ์ง ๋๊ณ ๋ง์ดํฌ๋กํ์คํฌ ํ๋ก ์ด๋ํ๊ฒ ๋ฉ๋๋ค.
await ํค์๋๋ฅผ ๋ง๋๋ฉด ๋น๋๊ธฐ ํจ์๊ฐ ์ผ์ ์ค์ง ๋๋ฏ๋ก ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ๋น๋๊ธฐ ํจ์(myFunc)์์ ๋น ์ ธ๋์จ ํ,
๋น๋๊ธฐ ํจ์๊ฐ ํธ์ถ ์คํ ์ปจํ ์ค(ํ์ฌ ์ฝ๋๋ myFunc์ ํธ์ถํ ๊ณณ์ ์ ์ญ ์คํ ์ปจํ ์คํธ)์์ ๊ณ์ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก ์ ์ญ ์ปจํ ์คํธ์์ ์คํํ ์ฝ๋๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ ๋ฃจํ๊ฐ ๋ง์ดํฌ๋กํ์คํฌ ํ์ ๋๊ธฐํ๋ ์์ ์ด ์๋์ง ํ์ธํฉ๋๋ค.
ํ์ธ ๊ฒฐ๊ณผ, myFunc์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ one ํจ์๊ฐ ํธ์ถ๋๊ณ ์ฝ ์คํ์์ ๋น ์ ธ๋๊ฐ๊ณ ์ค๋จ๋์๋ ์์น์ ๋ค์ ์คํ๋๊ฒ ๋ฉ๋๋ค.
๊ทธ๋์ ๋ง์ง๋ง์ผ๋ก console.log๋ฅผ ์ฝ ์คํ์ ์ถ๊ฐํ ํ ๋ฐํ ๋ res์ ๊ฐ์ ์ถ๋ ฅํ๊ณ ์ฝ ์คํ์์ ๋น ์ ธ๋์ค๊ฒ ๋๋ฉด์ ๋ง๋ฌด๋ฆฌ๊ฐ ๋ฉ๋๋ค.
aysnc / await์ Promise๋ ๋ชจ๋ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด์ง๋ง ๋์ ๋ฐฉ์์ ์ฐจ์ด์ ์ด ์์์ต๋๋ค.
- Promise: Promise ๊ฐ์ฒด๊ฐ resolve ๋๋ reject ๋๋ฉด .thene() ๋๋ .catch() ๋ด๋ถ์ ์ฝ๋ฐฑ ํจ์๊ฐ ๋ง์ดํฌ๋กํ์คํฌ ํ์ ์ถ๊ฐ๋ฉ๋๋ค.
- async / await: asyncํจ์ ๋ด์์ await ํค์๋๋ฅผ ๋ง๋๋ฉด, ํด๋น ํจ์์ ์คํ์ด ์ผ์ ์ค๋จ๋ฉ๋๋ค. ์ด๋ ๋ฐํ๋ ๊ฐ์ Promise ๊ฐ์ฒด์ ๋๋ค. await ํค์๋ ๋ค์ Promise๊ฐ resolve ๋๋ฉด, ๊ทธ ๊ฒฐ๊ณผ ๊ฐ์ await ํํ์ ์์ฒด๋ฅผ ๋์ฒดํ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋์ ํจ์์ ๋๋จธ์ง ๋ถ๋ถ์ด ๋ง์ดํฌ๋กํ์คํฌ ํ์ ์ถ๊ฐ๋์ด ํ์ ์ฒ๋ฆฌ๋ฉ๋๋ค.
๐ ๋ง์น๋ฉฐ
์๋ฐ์คํฌ๋ฆฝํธ์ ํต์ฌ ๊ฐ๋ ์ค ํ๋์ธ ์ด๋ฒคํธ ๋ฃจํ์ ๋ํด์ ์์๋ณด์์ต๋๋ค.
์ฒ์์๋ ๋ณต์กํ๊ฒ ๋๊ปด์ง๋ ๊ฑด ์ฌ์ค์ด์ง๋ง, ์ฌ๋ฌ ๋ฒ ๋ณด๊ณ ์ด๋ฒคํธ ๋ฃจํ์ ๊ฐ ํ์ ๋์ ๋ฐฉ์์ ์ตํ๋๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋์ ๋์ ์๋ฆฌ๋ฅผ ๊น๊ฒ ์ดํดํ๊ณ ์ฑ๋ฅ ์ต์ ํ์ ๋๋ฒ๊น ์์ ํฐ ๋์์ ์ป์ ์ ์๋ค๋ ์ ๋ ์๊ฒ ๋์์ต๋๋ค.
์ฐธ๊ณ ๋ฌธํ:
- https://talkwithcode.tistory.com/89
- https://youtu.be/8aGhZQkoFbQ?si=gviytHAw4tGHofJe
- https://baeharam.netlify.app/posts/javascript/event-loop
- https://pozafly.github.io/javascript/event-loop-and-async/
- https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif
- https://dev.to/lydiahallie/javascript-visualized-promises-async-await-5gke#syntax