...

Event loop
์ด๋ฒคํธ ๋ฃจํ๋ Node.js์ Main thread๋ก, ๋ด๋ถ์ ๊ฐ Phase๋ฅผ ๋๋ฉด์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํ ํฉ๋๋ค.
์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๊ฐ Phase๋ Queue๋ก ์ด๋ฃจ์ด์ ธ์์ต๋๋ค.
Queue์ ์ฐ๋ฆฌ๊ฐ ๋ฑ๋กํ Callback๋ค์ด ์๋ง๊ฒ ๋ด๊ฒจ์ ์์ ์ ์คํ์ ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๋๋ฐ์.
๊ฐ Phase๋ ์์ Queue์ ๋ชจ๋ Job์ ์ํํ๊ฑฐ๋, ์ ํ ๊ฐฏ์๊น์ง ์คํํ ํ์ ๋ค์ Phase๋ก ์ด๋ํฉ๋๋ค.

์ด ์ค์์ ์ฐ๋ฆฌ๋ timers, poll, check ๋จ๊ณ๋ง ํ์ํฉ๋๋ค.
Phase | ๋์ | ์ฒ๋ฆฌ ์์ |
timer | setTimeout(func, delay) setInterval(func, delay) |
delay๊ฐ ์ง๋ฌ์ผ๋ฉด, ๋ฑ๋ก๋ Callback ์คํ |
poll | I/O | ๋๋ถ๋ถ์ Callback ์คํ |
check | setImmediate(func) | ๋ฑ๋ก๋ Callback ์คํ |
setImmediate( )์ setTimeout( )
[JS] ๐ ์ค์ผ์ฅด๋ง setTimeout / setInterval
์ค์ผ์ฅด๋ง ์ผ์ ์๊ฐ์ด ์ง๋ ํ์ ์ํ๋ ํจ์๋ฅผ ์์ฝ ์คํ(ํธ์ถ)ํ ์ ์๊ฒ ํ๋ ๊ฒ์ 'ํธ์ถ ์ค์ผ์ค๋ง(scheduling a call)'์ด๋ผ๊ณ ํฉ๋๋ค. ํธ์ถ ์ค์ผ์ค๋ง์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ ๊ฐ์ง๊ฐ ์์ต๋๋ค. setTime
inpa.tistory.com
setImmediate( )์ setTimeout( )์ ๋น์ทํ์ง๋ง, ์ธ์ ํธ์ถ๋๋๋์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ํ๋ํฉ๋๋ค.
ํ์ด๋จธ๊ฐ ์คํ๋๋ ์์๋ ํธ์ถ๋๋ ์ฝํ ์คํธ ์์ ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค.
๋ง์ฝ ๋ ๋ค ๋ฉ์ธ ๋ชจ๋์์ ํธ์ถ๋๋ฉด, ํ๋ก์ธ์ค์ ์ฑ๋ฅ์ ๋ฐ๋ผ ํธ์ถ๋๋ ์์ ์ด ๋ค๋ฆ ๋๋ค. (์ด๊ฒ์ ๋จธ์ ์ ๋ค๋ฅธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํด ์ํฅ์ ๋ฐ์ ์ ์์ต๋๋ค. )
์๋ฅผ ๋ค์ด, ์๋ ์ฝ๋์ฒ๋ผ I/O ์ฌ์ดํด์ ์์ง ์์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํ์ํฌ ๋(๋ฉ์ธ ๋ชจ๋์ ์๋ ๊ฒฝ์ฐ), ๋ ๊ฐ์ ํ์ด๋จธ๊ฐ ์คํ๋๋ ์์๋ ํ์คํ์ง ์๊ณ , ํ๋ก์ธ์ค์ ํผํฌ๋จผ์ค์ ์ํด ๋ฌ๋ผ์ง๋๋ค.
// Execute
setTimeout(() => {
console.log('timeout');
}, 0);
setImmediate(() => {
console.log('immediate');
});
// Output 1
timeout
immediate
// Output 2
immediate
timeout

- setTimeout()์ Callback์ด timers์ ๋ฑ๋ก.
- setImmediate()์ Callback์ด check์ ๋ฑ๋ก.
- A. timers phase์ ๋๋ฌํ๋๋ฐ, 1ms ์ ์ timer phase๋ฅผ ํต๊ณผ ํ ๊ฒฝ์ฐ check phase์ setImmediate() ๊ฐ ๋จผ์ ์คํ
B. timers phase์ ๋๋ฌํ๋๋ฐ, 1ms๊ฐ ์ด๋ฏธ ๋์๋ค๋ฉด setTimeout() ์ด ๋จผ์ ์คํ
setTimeout(func, 0)์ 0ms๋ ๊ฒฐ๊ตญ 1ms๋ก ๋์ํฉ๋๋ค.
๊ทธ๋ฐ๋ฐ ๋ ๊ฐ์ ํธ์ถ์ I/O ์ฌ์ดํด์ ๋ฃ์ผ๋ฉด, immediate ์ฝ๋ฐฑ์ด ํญ์ ๋จผ์ ์คํ๋ฉ๋๋ค.
setTimeout( ) ๋ณด๋ค setImmediate( )๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ฅ์ ์ I/O ์ฌ์ดํด์ ์ค์ผ์ค ๋๋ค๋ฉด ์ผ๋ง๋ ๋ง์ ํ์ด๋จธ๊ฐ ์๋ ๊ฒ์ ์๊ด์์ด setTimeout( )์ด ์ธ์ ๋ ๋จผ์ ์คํ๋๋ค๋ ๊ฒ์ ๋๋ค.
// Execute
const fs = require('fs');
fs.readFile('a.js', (result) => {
setTimeout(() => {
console.log('timeout');
}, 0);
setImmediate(() => {
console.log('immediate');
});
});
// Output
immediate
timeout


- fs.readFile() ์ด ์คํ๋๊ณ , Callback์ด poll์ ๋ค์ด๊ฐ๋๋ค.
- poll phase์ ์ง์ ํ๊ณ , Callback์ด ์คํ๋๋ฏ๋ก setTimeout() ์ Callback์ด timers phase์ ๋ค์ด๊ฐ๋๋ค.
- setImmediate() ์ Callback์ด check phase์ ๋ค์ด๊ฐ๋๋ค.
- poll phase๋ฅผ ๋ชจ๋ ์์งํ์ผ๋, ๋ค์ phase์ธ check phase๋ก ์ด๋ํ ๊ฒ์ ๋๋ค.
๊ฐ์ I/O ์ฃผ๊ธฐ ๋ด์์๋ Immediate๊ฐ ๋จผ์ ์คํ๋ฉ๋๋ค.
process.nextTick( )
๊ณต์ ๋ฌธ์์ ๋ฐ๋ฅด๋ฉด process.nextTick()์ Event loop์ ์ผ๋ถ๊ฐ ์๋๋ฉฐ, nextTickQueue๋ ํ์ฌ ์งํ ์ค์ธ ์์ ์ด ๋๋๋ฉด ์คํ๋๋ค๊ณ ๋์์์ต๋๋ค.
- process.nextTick(cb)์ next tick queue์ ๋ค์ด๊ฐ๋ฉฐ, ๊ฐ phase์ฌ์ด์ฌ์ด์์ ํธ์ถ๋ฉ๋๋ค
- process.nextTick(cb)์ timer phase(timer queue)์ดํ๋ถํฐ ํธ์ถ๋ ๊ฒ ๊ฐ์ง๋ง, ์ค์ ๋ก๋ ๋จผ์ ํธ์ถ๋ฉ๋๋ค
// Execute
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
process.nextTick(() => {
setTimeout(() => console.log('timeout2'), 0);
setImmediate(() => {
process.nextTick(() => console.log('next tick2'));
console.log('immediate2');
});
console.log('next tick');
});
// Output
next tick
timeout
timeout2
immediate
immediate2
next tick2


- setTimeout() ์ Callback์ด timers phase์ ๋ด๊น๋๋ค. 1๋ฒ ์์ ์ ๊ฐ์ด 0ms๋ 1ms๊ฐ ๋ฉ๋๋ค.
- setImmediate() ์ Callback์ด check phase์ ๋ด๊น๋๋ค.
- process.nextTick() ์ Callback์ด nextTickQueue์ ๋ด๊น๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์ nextTickQueue ์ค๋ช ์ ๋ฐ๋ผ ์ ์ผ ๋จผ์ ์คํ๋ฉ๋๋ค.
- nextTickQueue์ Callback์ธ setTimeout(), setImmediate()์ Callback์ด ๊ฐ๊ฐ phase์ ๋ด๊ธฐ๊ฒ ๋ฉ๋๋ค.
- ์ดํ ์ด๋ค์ด ์คํ๋๊ณ , ๊ทธ์ ๋ฐ๋ผ ์์ ์์ ์ Output์ ํด๋นํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค๊ฒ ๋์์ต๋๋ค.
Promise์ ํ์ nextTickํ ์ค์ ์ด๋๊ฒ ๋จผ์ ์คํ๋ ๊น์?
๊ฐ๋จํ๊ฒ ์๊ฐํ๋ฉด ๋ฉ๋๋ค. nextTick ํ๊ฐ ์ด๋์ํฉ์ด๋ ๊ฐ์ฅ ๋จผ์ ์คํ๋๋ค!
์ด๋ฒคํธ ๋น๋๊ธฐ ์คํ์์ : nextTick -> Promise -> setTimeout
# ์ฐธ๊ณ ์๋ฃ
https://short-term.tistory.com/8
https://medium.com/@rpf5573/nodejs-event-loop-part-2-settimeout-vs-setimmediate-vs-process-nexttick-70ba2a9f0895
์ด ๊ธ์ด ์ข์ผ์ จ๋ค๋ฉด ๊ตฌ๋ & ์ข์์
์ฌ๋ฌ๋ถ์ ๊ตฌ๋
๊ณผ ์ข์์๋
์ ์์๊ฒ ํฐ ํ์ด ๋ฉ๋๋ค.