Open BKJang opened 5 years ago
์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๊ณต๋ถํด๋ณธ ๊ฐ๋ฐ์๋ผ๋ฉด ํ ๋ฒ์ฏค์ ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ฑ๊ธ ์ฐ๋ ๋ ๊ธฐ๋ฐ์ ์ธ์ด๋ค.
๋ผ๋ ๋ง์ ๋ค์ด๋ดค์ ๊ฒ์ด๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๋ ์ค์ ์น ์ ํ๋ฆฌ์ผ์ด์
์์ ์ฌ๋ฌ ๊ฐ์ ์์
์ด ๋์์ ์ฒ๋ฆฌ๋๋ ๊ฒ์ฒ๋ผ(๋น๋๊ธฐ์ ) ๋๋ผ๋ ์ผ์ด ๋ ๋ง๋ค. ์ฑ๊ธ ์ฐ๋ ๋ ๊ธฐ๋ฐ์ ์ธ์ด์์ ์ฆ, ํ ๋ฒ์ ํ๋์ ์์
๋ง ์ฒ๋ฆฌ๊ฐ๋ฅํ ํ๊ฒฝ์์ ์ด๋ป๊ฒ ๋ง์ ์์
์ด ๋์์ ์ฒ๋ฆฌ๋๋ ๊ฒ์ฒ๋ผ ๋๋ ์ ์์๊น? ๊ทธ ๋ต์ ์ด๋ฒคํธ ๋ฃจํ์ ์๋ค.
๋ธ๋ผ์ฐ์ ํ๊ฒฝ์ ๊ฐ๋จํ ํํํ๋ฉด ๋ค์ ์ด๋ฏธ์ง์ ๊ฐ๋ค.
์ฐ์ , ์์ ๊ทธ๋ฆผ์์ ๋ณด์ฌ์ง๋ ๊ฐ๊ฐ์ ๋ํด์ ์ดํด๋ณธ ํ, ์ ์ฒด์ ์ผ๋ก ์ด๋ฒคํธ ๋ฃจํ๊ฐ ๋์ํ๋ ๋ฐฉ์์ ์ดํด๋ณด๋๋ก ํ์.
๋์ ์ผ๋ก ์์ฑ๋ ๊ฐ์ฒด ์ธ์คํด์ค๋ Heap์ ํ ๋น์ด ๋๋ค. Heap์ ๋ฉ๋ชจ๋ฆฌ์์ ๋๋ถ๋ถ ๊ตฌ์กฐํ๋์ง ์์ ์์ญ์ ๋ํ๋ธ๋ค.
ํธ์ถ ์คํ์ ์ด๋ฆ ๊ทธ๋๋ก Stack
์ด๋ฉฐ LIFO(Last-In-First-Out)๊ตฌ์กฐ๋ฅผ ๊ฐ๋๋ค. ํจ์๋ฅผ ํธ์ถํ๋ฉด(์์
์ ์์ฒญํ๋ฉด) ์์
์ ์์ฐจ์ ์ผ๋ก ํธ์ถ ์คํ์ ์์ด๊ณ ์คํ๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ํ๋์ ์คํ๋ง ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ํ๋์ ์์
์ด ๋๋๊ธฐ ์ ๊น์ง ๋ค๋ฅธ ์์
์ ์ํํ ์ ์๋ค.
ํํ WebAPI๋ผ ๋ถ๋ฆฌ๋ API๋ค์ ์คํํ๊ฒฝ์ ๋ด์ฅ๋์ด ์๋ค.
์ด๊ฒ์ ์๋ฐ์คํฌ๋ฆฝํธ์ ํฌํจ๋๋ ๊ฒ์ด ์๋๋ค. ์ฆ, ์ฐ๋ฆฌ๋ Web API์ ๋ด๋ถ๋ ์กฐ์ํ ์ ์์ผ๋ฉฐ ํธ์ถ๋ง ๊ฐ๋ฅํ๋ค. ๋ํ ์๋ฐ์คํฌ๋ฆฝํธ ์ธ์ด๋ฅผ ์ฌ์ฉํ๋๋ฐ ์์ด ๊ฐ๋ ฅํ ์ฑ๋ฅ์ ์ ๊ณตํ๋ค.
Web API์ ์ข ๋ฅ๋ ๋ค์์ ์ฐธ์กฐํ๋ฉด ์ ์ ์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ์ฑ๊ธ ์ฐ๋ ๋ ๊ตฌ์กฐ์์ ๋น๋๊ธฐ์ฑ์ ์ด๋ฒคํธ ๊ธฐ๋ฐ ์คํ(๋ํ์ ์ผ๋ก setTimeout
)์ด๋ ajax
์์ฒญ์ด ํ์ํ๋ค๋ฉด, ์ฝ๋ฐฑ ํจ์๋ฅผ ํ๋ก ๋ณด๋ด๊ณ ํ์์๋ ํธ์ถ ์คํ์ผ๋ก ๋ณด๋ด ํด๊ฒฐํ๊ฒ ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์๋ ์ฐ๋ ๋๋ฅผ ํตํด ๋ณ๋ ฌ์ฒ๋ฆฌ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ์ฝ๋ฐฑ ํจ์์ ์ฌ์ฉ์ ํ์๋ถ๊ฐ๊ฒฐํ๊ฒ ๋๋ ๊ฒ์ด๋ค.
์ด๋ฒคํธ ํ๋ ๋ง ๊ทธ๋๋ก ์ฝ๋ฐฑ ํจ์๋ค์ด ๋๊ธฐํ๋ Queue
์ด๋ฉฐ FIFO(First-In-First-Out)
์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋๋ค. ์ด๋ฒคํธ ๋ฃจํ๋ ํธ์ถ ์คํ์ด ๋น์์ง ๋๋ง๋ค ํ์์ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถ ์คํ์ ๋ฃ์ด์ฃผ๋ ์ญํ ์ ํด์ค๋ค.
์ด๋ฒคํธ ๋ฃจํ์ ์ญํ ์ ์๊ฐ๋ณด๋ค ๋จ์ํ๋ค. ํธ์ถ ์คํ์ ์คํ ์ค์ธ ์์ ์ด ์๋์ง, ์ด๋ฒคํธ ํ์ ๋๊ธฐ ์ค์ธ ์์ ์ด ์๋์ง ๋ฐ๋ณตํด์ ํ์ธํ๋ค. ๋ง์ฝ ํธ์ถ ์คํ์ด ๋น์ด์๋ค๋ฉด ์ด๋ฒคํธ ํ์ ์๋ ์์ ์ ํธ์ถ ์คํ์ผ๋ก ์ฎ๊ธด๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ์์ ์ ์ํํ๋ ๊ฒ์ ๊ฒฐ๊ตญ ํธ์ถ ์คํ์ด๋ค.
function func1() {
console.log('func1');
func2();
}
function func2() {
setTimeout(function () {
console.log('func2');
}, 0);
func3();
}
function func3() {
console.log('func3');
}
func1();
์ ์์ ๋ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์ค๋ช
ํ ๋ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ์์ ๋ค. ๋ง์ฝ, ์ด๋ฒคํธ ๋ฃจํ๊ฐ ์ํํ๋ ๊ณผ์ ์ด ์๊ณ ์์ฐจ์ ์ผ๋ก ํธ์ถ ์คํ์๋ง ์์ด๊ฒ ๋๋ค๋ฉด func1
, func2
, func3
์ ์์๋ก ์ถ๋ ฅ๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์ค์ ๋ก ์ ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด func1
, func3
, func2
์ ์์๋ก ์ถ๋ ฅ๋๋ ๊ฒ์ ๋ณผ ์ ์์ ๊ฒ์ด๋ค. ์ด๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋ ์ด์ ๋ ์์์ ์ค๋ช
ํ ๊ฒ ์ฒ๋ผ ์ด๋ฒคํธ ํ์ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ํตํด ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ setTimeout
ํจ์๊ฐ ๋ค๋ฅธ ํจ์๋ค๊ณผ ๋ค๋ฅด๊ฒ ๋์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ ์ด๋ฏธ์ง๋ ์ ์ฝ๋๊ฐ ์คํ๋๋ ๊ณผ์ ์ ๋ณด์ฌ์ค๋ค.
์ด๋ฏธ์ง ์ถ์ฒ: https://poiemaweb.com/js-event
์ ๊ณผ์ ์ ์์ฐจ์ ์ผ๋ก ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
func1
ํจ์๊ฐ ํธ์ถ๋๊ณ ์ด๋ ํธ์ถ ์คํ์ ์ฌ๋ผ๊ฐ๊ณconsole.log('func1')
์ด ์คํ๋๋ค.func2
ํจ์๊ฐ ํธ์ถ ์คํ์ ์ฌ๋ผ๊ฐ๊ณsetTimout
ํจ์๋ฅผ ํธ์ถํ๋ค.- ํธ์ถ๋
setTimeout
ํจ์์ ์ํ์ ๋น๋๊ธฐ์ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ Web API์ ๋์ด๊ฐ๋ค.func3
ํจ์๊ฐ ํธ์ถ ์คํ์ ์ฌ๋ผ๊ฐ๊ณconsole.log('func3')
์ด ์คํ๋๋ค.- Web API์์
setTimout
ํจ์์์ ์ง์ ํ ์๊ฐ์ด ์ง๋๋ฉดcallback
ํจ์๋ฅผ ์ด๋ฒคํธ ํ๋ก ๋๊ธด๋ค.- ์์ ์ด ๋๋
func3
,func2
,func1
์ ์์ฐจ์ ์ผ๋ก ํธ์ถ ์คํ์์ ์ ๊ฑฐ๋๋ค.- ์ด๋ฒคํธ ๋ฃจํ๋ ํธ์ถ ์คํ์ ์์ ์ค์ธ ํ์คํฌ๊ฐ ์๋ ๊ฒ์ ํ์ธํ๊ณ ์ด๋ฒคํธ ํ์ ์๋
callback
ํจ์๋ฅผ ํธ์ถ ์คํ์ผ๋ก ์ฌ๋ฆฐ๋ค.- ํธ์ถ ์คํ์ ์ฌ๋ผ๊ฐ
callback
ํจ์๊ฐ ์คํ๋๋ฉด์console.log('func3')
๊ฐ ์คํ๋๋ค.
์ ์ค๋ช
์์ ์ฃผ์ ๊น๊ฒ ๋ณผ ๊ฒ์ ๋น๋๊ธฐ ํจ์์ธ setTimeout
ํจ์์ ์ธํ
๋ ์๊ฐ์ด 3์ด๋ผ๋ฉด 3์ด ํ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์คํ์์ผ๋ผ
๊ฐ ์๋ 3์ด ํ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ด๋ฒคํธ ํ์ ๋ฃ์ด๋ผ
๊ฐ ๋๋ค๋ ๊ฒ์ด๋ค.
์ฆ, setTimeout
ํจ์๋ n์ด ๋ค์ ์ฝ๋ฐฑ์ ๋จ์ํ ํ์ ์ง์ด๋ฃ๋๊ฒ ๋์ด๋ค. ์ฝ๋๋ฅผ ๊ฐ๋จํ ๋ณด์๋ฉด ์๋์ ๊ฐ๋ค.
var eventLoop = [];
var event;
while (true) {
// ํฑ!
if (eventLoop.length > 0) {
event = eventLoop.shift();
}
try {
event(); // ํธ์ถ์คํ์ผ๋ก ๋ฐ์ด๋ฃ๋๋ค
} catch (err) {
//...
}
}
์ด ํ์ ์ด๋ฏธ ๋๊ธฐ๋ฒํธ๊ฐ 100๊ฐ๊ฐ ์๋ค๋ฉด func3
๋ 101๋ฒ์งธ ๋๊ธฐํ๋ฅผ ๋ฐ๊ฒ ๋ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ setTimeout
์ ์ง์ ํ ์๊ฐ๋์์ ์คํ๋์ง ์๋ ๊ฒ์ ๋ณด์ฅํ ์ ์์ง๋ง ์ง์ ํ ์๊ฐ์ ์คํ๋๋๊ฒ์ ๋ณด์ฅํ ์ ์๋ค.
while (await messageQueue.nextMessage()) {
let message = messageQueue.shift();
message.run();
}
๊ฒฐ๋ก ์ ์ผ๋ก, ์ด๋ฒคํธ ๋ฃจํ๋ ๋ฉ์์ง ํ์ ๋ฉ์์ง๊ฐ ๋ ์๋์ง ํ์ธํ๋ ๋ฃจํ์ด๋ค.
๋ฉ์์ง ํ์ ๋ฉ์์ง๊ฐ ์์ผ๋ฉด ๋ฉ์์ง ํ์์ ๋ค์ ๋ฉ์์ง๋ฅผ ์ ๊ฑฐํ๊ณ ๊ทธ ๋ฉ์์ง์ ์ฐ๊ด๋ ๊ธฐ๋ฅ์ ํธ์ถ ์คํ์ผ๋ก ๋ณด๋ธ๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ ๋ฉ์์ง๊ฐ ๋ฉ์์ง ๋๊ธฐ์ด์ ์ถ๊ฐ๋ ๋๊น์ง ๋๊ธฐ๋ฅผ ํ๋ค. ์ด๋ฒคํธ ๋ฃจํ๊ฐ ์๋ฐ์คํฌ๋ฆฝํธ์๊ฒ ๋น๋๊ธฐ๋ฅผ ํ์ฉํ๋ ๊ธฐ๋ณธ ๋ชจ๋ธ์ด๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ฒคํธ ๋ฃจํ๋ ์์์ ์ค๋ช
ํ ๋ด์ฉ์ด ํฐ ํ์ด๋ค. ํ์ ์คํ์ ๊ฐ์ํ๋ฉฐ ์คํ์ ์์
์ด ์์ผ๋ฉด ํ์ ์์
์ ์คํ์ ์ฌ๋ฆฐ๋ค. ๋ค๋ง, ES6
์ดํ์๋ ๋ช ๊ฐ์ง ๋น๋๊ธฐ์ ์์
์ ์ํํ๋ API๋ค์ด ์ถ๊ฐ๋์๊ณ ์ด์ ๋ฐ๋ผ ์ฝ๊ฐ์ ์ถ๊ฐ๋ ๋ด์ฉ์ด ์๋ค. ํ์ง๋ง, ์ ์ฒด์ ์ธ ์คํ ๋ฐฉ์์ ๋์ผํ๋ฉฐ ๊ฐ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ์ํ ์์์ ์ด์ ์ ๋๊ณ ์ดํด๋ณด์.
๊ธฐ์กด์ ์ดํด๋ณด์๋ ์ด๋ฒคํธ ํ(Event Queue)๋ฅผ ์ข ๋ ์์ธํ ๋๋ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
Task Queue
: ๊ฐ์ฅ ์ฌ๋๋ค์ด ์ ์๊ณ ์๋ ๋น๋๊ธฐ ์์
์ธ setTimeout
์ด ๋ค์ด๊ฐ๋ ํMicro Task Queue
: ES6์์ ์ถ๊ฐ๋ Promise
์ ES8์ Async Await
(Async Await๋ ๊ฒฐ๊ตญ Promise)AnimationFrame
: requestAnimationFrame(rAF)
์ ์ฝ๋ฐฑ ํจ์๊ฐ ๋ค์ด๊ฐ๋ค.console.log("script start");
setTimeout(function() {
console.log("setTimeout");
}, 0);
Promise.resolve().then(function() {
console.log("promise1");
}).then(function() {
console.log("promise2");
});
requestAnimationFrame(function {
console.log("requestAnimationFrame");
})
console.log("script end");
์์ ์ฝ๋๋ฅผ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋๋ค.
script start
script end
promise1
promise2
requestAnimationFrame
setTimeout
์ฆ, ์ด๋ฒคํธ ํ์์ ๋๋ ์ง๋ 3๊ฐ์ง ์์ญ์ ์ฐ์ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
Micro Task Queue => AnimationFrame => Task Queue
๊ธฐ์กด์ ์ด๋ฒคํธ ๋ฃจํ์ ๋ํด์ ์ดํด๊ฐ ๋ ์ํ๋ผ๋ฉด ์ด ๋ด์ฉ์ ํฌ๊ฒ ์ด๋ ต์ง ์๋ค. ์ฝ๊ฒ ๋ณด๋ฉด ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ์ถ๊ฐ๋์๊ณ ์ด์ ๋ฐ๋ผ ์ด๋ฒคํธ ํ์์ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ก์ง์ ์ฝ๊ฐ์ ๋ณํ๊ฐ ์๊ฒผ์ ๋ฟ์ด๋ค. ๊ฒฐ๊ตญ, ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
Task
์ Micro Task
, ๊ทธ๋ฆฌ๊ณ AnimationFrame
์ผ๋ก ๊ตฌ๋ถ๋๋ค.Micro Task
๋ Task
๋ณด๋ค ๋จผ์ ์ฒ๋ฆฌ๋๋ค.Micro Task
๊ฐ ์ฒ๋ฆฌ๋ ์ดํ requestAnimationFrame
์ด ํธ์ถ๋๊ณ ์ดํ ๋ธ๋ผ์ฐ์ ๋๋๋ง์ด ๋ฐ์ํ๋ค.
๐ Reference