์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ฒ๋ฆฌ / Promise / async / await / fetch
๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ตฌ์กฐ
์๋ฐ์คํฌ๋ฆฝํธ๋ ์๋ ์ฑ๊ธ ์ค๋ ๋ ๊ธฐ๋ฐ ์ธ์ด์ด๋ฉฐ ๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ค. ํธ์ถ ์คํ(Call Stack)์ด ํ๋์ฌ์ ์คํ ๋ด์ ์์ธ ์์ ์ ์์๋๋ก ์ฒ๋ฆฌํ๋ค.
ํ์ง๋ง, ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์ฝ๋๊ฐ ์์ผ๋ฉด ๊ทธ ์์ ์ด ๋๋๊ณ ์ฝ๋ฐฑํ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ๋ค์ ์์ ์ ์ฒ๋ฆฌํ๊ฒ ๋๋ค. ๊ทธ ์๊ฐ ๋์์ ๋๊ธฐํด์ผ ํ๋ฏ๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ํ์ํ๋ค.
setTimeout() ์ผ๋ก ์ผ์ ์๊ฐ ๋์ ์์ ์ ์ง์ฐ์ํค๋ ์์์ด๋ค. ์ด ์์ ๋ฅผ ์คํํ๋ฉด 3์ด ๋ค์ '3์ด ์ง์ฐ!'์ด๋ผ๋ ๋ฌธ๊ตฌ๋ฅผ ์ฐ๋๋ค.
setTimeout(function() {
console.log('3์ด ์ง์ฐ!');
}, 3000);
์ง๊ธ์ 3์ด์ง๋ฆฌ ์ฝ๋์ด์ง๋ง, ์๋ฒ์์ ๋๋์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ๋ฑ์ ์ฒ๋ฆฌ๊ฐ ํ์ํ ๋๋ ๋ ์๊ฐ์ด ๊ธธ์ด์ง๊ฒ ๋๋ค. ๊ทธ ์๊ฐ ๋์ ๋ค์ ์ฝ๋๋ฅผ ์คํํ์ง ์๊ณ ๊ธฐ๋ค๋ฆฌ๋ฉด ์ฌ์ฉ์๋ ๊ณ์ ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๋ค.
๊ทธ๋์ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํด ์ค๋ ๊ฑธ๋ฆฌ๋ ์์ ๋ค์ ๋๊ฒจ์ ์ฒ๋ฆฌํ๋ค. ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ธ๋ถ API ์ ์์ํ๊ณ ์๋ฃ๋ ์์ ์ event loop ๋ฅผ ํตํด ๋ฐํ ๋ฐ๊ณ ๋ค์ ์ฝ๋ฐฑ์ ์คํํ์ฌ ๋ณ๋ ฌ์ ์ผ๋ก ๋น๋๊ธฐ ์ฝ๋๋ฅผ ์คํํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค.
setTimeout() ์ ์ธ์๋ก ๋ฐ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ธ๋ถ API์ ์์ฝํ๊ธฐ๋ง ํ๊ณ ๊ธฐ๋ค๋ฆฌ๋ ๊ฑด ์๋ ์ฝ๋๋ ์๊ด์์ด ๋ฐ๋ก ๋์ํ๋ค. ์ด๊ฒ์ด ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ด๋ค.
setTimeout ํจ์๊ฐ ์คํ๋๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ์ ๊ณตํ๋ Web API ๋ฅผ ํธ์ถํ๊ณ Call Stack์์ ์ ๊ฑฐํ๋ค. ์ผ์ ์๊ฐ์ด ์ง๋ ๋ค ๋๋ ์์ ์ callback queue์ ๋ฃ๋๋ค. event loop๋ call stack์ ๊ฐ์ํ๋ค๊ฐ ๋น์ด์์ผ๋ฉด callback queue์ ์๋ ์ฝ๋ฐฑ ํจ์๋ฅผ call stack์ ๋๊ธฐ๊ณ ์คํํ๋ค. (์ค์ ๋ก setTimeout์ ์ฃผ์ด์ง ์๊ฐ์ callback queue์ ๋ค์ด๊ฐ๋ ์๊ฐ์ผ ๋ฟ ์คํ๊น์ง ๊ฑธ๋ฆฌ๋ ์๊ฐ์ด ์๋ ์๋ ์๋ค.)
์๋ ์์๋ setTimeout() 0์ด, 3์ด ์ง๋ฆฌ๋ฅผ ์คํํ์ ๋์ ์ฝ๋์ด๋ค.
console.log('11111');
setTimeout(
function() {
console.log('22222');
}
, 0);
setTimeout(
function() {
console.log('33333');
}
, 3000);
console.log('44444');
'22222'๋ฅผ ์ฐ๋ ์ฝ๋๋ 0์ด ์ง์ฐ ํ ์คํ๋์ด์ผ ํ์ง๋ง ์ธ๋ถ API๋ก ์์๋๊ณ 0์ด ํ ์ฝ๋ฐฑ ํ์ ๋ค์ด์ ๊ธฐ๋ค๋ฆฌ๋ค๊ฐ ์ฝ ์คํ์ด ๋น ํ์ ์คํ๋๋ฏ๋ก ์ถ๋ ฅ ์์๋ '11111' → '44444' → '22222' → '33333'๊ฐ ๋๋ค.
promise
ES6 ๋ถํฐ๋ Promise๋ก ๋น๋๊ธฐ ์์ ์ ๊ด๋ฆฌํ ์ ์๋ค.
์ฝ๋ฐฑ์ด ์๋ Promise๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ ์ด์ ๋ ์ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ์ธ์.
์ฐธ๊ณ ๋ก Promise๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ์ง๋ง callback queue๊ฐ ์๋ job queue๋ฅผ ์ฌ์ฉํ๊ณ ์ด๋ callback queue๋ณด๋ค ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๋ค.
๋น๋๊ธฐ ์์ ์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ด๋ค. Promise ์์ฑ์๋ ์ธ์๋ก executor ํจ์๋ฅผ ๋ฐ์ผ๋ฉฐ Promise ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
executor ํจ์๋ resolve, reject ๋ ๊ฐ์ ์ธ์๋ฅผ ๊ฐ์ง๊ณ ์ด๋ค๋ ๋ชจ๋ ํธ์ถํ ์ ์๋ ํจ์์ด๋ค. ์์ ์ ์ฑ๊ณตํ ๊ฒฝ์ฐ resolve, ์คํจํ ๊ฒฝ์ฐ reject๋ฅผ ํธ์ถํ๋ฉฐ ์ด์ ๋ฐ๋ฅธ ์์ ์ ์ง์ ํ ์ ์๋ค.
const promise = new Promise((resolve, reject) => {
// ์ฒ๋ฆฌํ ๋น๋๊ธฐ ์์
});
๋น๋๊ธฐ ์์ ์ด ๋๋ ์ดํ์ ํด์ผ ํ ์์ ์ ์ง์ ํ๋ ค๋ฉด ์ฑ๊ณตํ์ ๋๋ then(), ์คํจํ์ ๋๋ catch()๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ์ ํจ์๋ค์ ์ฒด์ธ ํํ๋ก ์ฌ๋ฌ ๊ฐ๋ฅผ ์ด์ด ์ฐ์์ ์ผ๋ก ์ฌ์ฉํ ์๋ ์๋ค.
promise
.then(() => {
console.log("์ฑ๊ณต, then!");
})
.catch(() => {
console.log("์คํจ, catch!");
});
promise ๊ฐ์ฒด๊ฐ resolve()๋ฅผ ํธ์ถํ๋ฉด then, reject()๋ฅผ ํธ์ถํ๋ฉด catch๊ฐ ์คํ๋๋ค.
async/await
์๋ฐ์คํฌ๋ฆฝํธ์์ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ธ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ, Promise๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์์ ๊ทธ ๋จ์ ๋ค์ ๋ณด์ํ ๊ฒ์ด aync/await์ด๋ค.
์์์ ์์ฑํ๋ Promise๋ฅผ async๋ก ๋ณ๊ฒฝํด๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
async๋ promise๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ ํ ์์ ์ promise๋ฅผ ์ด์ฉํ๋ฉด ๋๋ค.
// Promise
const promise = new Promise((resolve, reject) => {
// ์ฒ๋ฆฌํ ๋น๋๊ธฐ ์์
});
// async
async function asyncFunction() {
// ์ฒ๋ฆฌํ ๋น๋๊ธฐ ์์
}
const promise = asyncFunction();
...
์ฌ๊ธฐ์ await๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด Promise ๊ฐ์ฒด์ then(), catch()๋ก ์ฌํ ์์ ์ ์ฒ๋ฆฌํ๋ ๊ฒ๋ณด๋ค ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ด๋ค.
ํจ์ ์์ async ์์ฝ์ด๋ฅผ, ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ฝ๋ ์์ await๋ฅผ ๋ถ์ด๋ฉด ๋๋ค. await๋ async ์์์๋ง ๋์ํ๋ค.
function fetchHello() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
var greet = 'hello';
resolve(greet);
}, 3000);
});
}
async function printHello() {
var result = await fetchHello();
console.log(result);
}
printHello();
console.log('bye');
// bye ์ถ๋ ฅ ํ 3์ด ๋ค hello
await๋ fetchHello ๊ฐ ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ๊ทธ ์๋์ ์ฝ๋๋ฅผ ์คํํ ๊ฒ์ด๊ณ printHello ํจ์๋ async ์ด๋ฏ๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌ๋๋ค. Promise์์ ์ค๋ฅ ๋ฐ์ ์ reject, catch()๋ก ์ฒ๋ฆฌํ๋๋ฐ async/await์์๋ await ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ค๋ ์ชฝ์์ try~catch ๋ฌธ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
fetch
๋น๋๊ธฐ ์ฒ๋ฆฌ๋ ์ฃผ๋ก ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ๊ณผ ๊ฐ์ด ์๊ฐ์ด ๋ง์ด ์์๋๋ ์์ ์ ์ฌ์ฉ๋๋ค.
์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ ๋ XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฒด ํ์ด์ง์ ๋ฆฌ๋ก๋ ์์ด๋ URL ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ ์ ์๋ค. ajax๋ XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ์์์ด๋ค. ์๋ฐ์คํฌ๋ฆฝํธ๋ก XMLHttpRequest()์ Promise๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ํต์ ์ ๊ตฌํํ๋ ์ฝ๋๋ ๋๋ฌด ๋ณต์กํ๋ค. ๊ทธ๋์ ES6๋ถํฐ XMLHttpRequest() ๋์ fetch API๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
fetch๋ Promise๋ฅผ ๋ฐํํ๋ฉฐ ์๋์ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
// XMLHttpRequest() ์ฌ์ฉ
const request = new XMLHttpRequest();
request.open('GET', URL);
// fetch API ์ฌ์ฉ
const request = fetch(URL);