...

์ฝ๋ฐฑ ์ง์ฅ์ ํ์ถํ๋ ์๋ก์ด ๋ฌธ๋ฒ
์๋ฐ์คํฌ๋ฆฝํธ์์ '๋น๋๊ธฐ ์ฒ๋ฆฌ' ๋ ํ์ฌ ์คํ์ค์ธ ์์ ๊ณผ๋ ๋ณ๋๋ก ๋ค๋ฅธ ์์ ์ ์ํํ๋ ๊ฒ์ ๋งํ๋ค. ์๋ฅผ ๋ค์ด ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ์์ ์ ์๊ฐ์ด ๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ์ ์๋ฐ์คํฌ๋ฆฝํธ์ ์๋ฒ ํธ์ถ ํจ์๋ ๋น๋๊ธฐ ํจ์(--๋งํฌ--)๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
๋น๋๊ธฐ๋ ํน์ ์ฝ๋์ ์คํ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ค์ ์ฝ๋๋ฅผ ๋จผ์ ์ํํ๋ ๋ฐฉ์์ด๊ธฐ ๋๋ฌธ์, ๋ง์ผ ๋น๋๊ธฐ ์์ ์ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋ค๋ฅธ ์์ ์ ์ํํด์ผ ํ ๋๋ ์ ํต์ ์ผ๋ก ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฌ์ฉํ๋ค. ์ฝ๋ฐฑ ํจ์๋ ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋๋ฉด ํธ์ถ๋๋ ํจ์์ ์๋ฏธ๋ก์, ๋น๋๊ธฐ ํจ์์ ๋งค๊ฐ๋ณ์๋ก ํจ์ ๊ฐ์ฒด๋ฅผ ๋๊ธฐ๋ ๊ธฐ๋ฒ์ ๋งํ๋ค. ๊ทธ๋์ ํจ์ ๋ด๋ถ์์ ํจ์ ํธ์ถ์ ํตํด ๋น๋๊ธฐ ์์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์ ์ธ์๋ก ์ฃผ๋ฉด ์ด๋ฅผ ํตํด ํ์ ์ฒ๋ฆฌ ์์ ์ ์ํํ ์ ์๋ค. ํ์ง๋ง ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋๊ฐ ๋ณต์กํ๊ณ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๋ ๋ฌธ์ ๊ฐ ์๋ค. ํนํ, ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์์ ์ ์์ฐจ์ ์ผ๋ก ์ํํด์ผ ํ ๋๋ ์ฝ๋ฐฑ ํจ์๊ฐ ์ค์ฒฉ๋์ด ์ฝ๋์ ๊น์ด๊ฐ ๊น์ด์ง๋ ํ์์ด ๋ฐ์ํ๋ค. ์ด๋ฌํ ํ์์ ์ฝ๋ฐฑ ์ง์ฅ(callback hell) ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์ฝ๋ฐฑ ํจ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฌธ๋ฒ
์ซ์ n ์ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์์์ ๋ค์ฏ๋ฒ์ ๊ฑธ์ณ 1์ด๋ง๋ค 1์ฉ ๋ํด์ ์ถ๋ ฅํ๋ ์์
์ setTimeout ๋น๋๊ธฐ ํจ์๋ก ๊ตฌํํ ์ฝ๋์ด๋ค. ํ๋์ ๋ด๋ ์ฝ๋ฐฑํจ์๋ฅผ ์ฐ๋ฌ์ ์จ์ ์ฝ๋์ ๊น์ด๊ฐ ๊น์ด์ก๋ค. ๋ณด๊ธฐ์ ๋งค์ฐ ์์ข์ ๊ฑธ ๋ณผ ์ ์๋ค.
function increaseAndPrint(n, callback) {
setTimeout(() => {
const increased = n + 1;
console.log(increased);
if (callback) {
callback(increased); // ์ฝ๋ฐฑํจ์ ํธ์ถ
}
}, 1000);
}
increaseAndPrint(0, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
console.log('๋!');
});
});
});
});
});
์ฝ๋๊ฐ ๋ง์น '์๋ด๊ฒ'โ ์ ๋ง์ ๊ฒ์ฒ๋ผ ๋ค์ฌ์ฐ๊ธฐ ์ฝ๋์ ๊น์ด๊ฐ ํ ์ฒ๋ผ ํ์ด์ ธ ์๋ ์๊ธฐ๋ ๋ชจ์ต์ด๋ค.

์ด๋ฌํ ์ฝ๋ฐฑ ํจ์์ ์ฝ๋ ํํ๋ ์ฝ๋ฐฑ ํจ์๊ฐ ์ค์ฒฉ๋๋ฉด์ ๋ค์ฌ์ฐ๊ธฐ ์์ค์ด ๊น์ด์ ธ ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋จ์ด๋จ๋ฆฌ๋ฉฐ ์ฝ๋์ ํ๋ฆ์ ํ์ ํ๊ธฐ ์ด๋ ค์์ง๋ค. ๋ํ ์ฝ๋ฐฑ ํจ์๋ง๋ค ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ๋ฐ๋ก ํด์ค์ผ ํ๊ณ , ์๋ฌ๊ฐ ๋ฐ์ํ ์์น๋ฅผ ์ถ์ ํ๊ธฐ ํ๋ค๊ฒ ๋๋ค.
ํ๋ก๋ฏธ์ค๋ก ๊ฐ์ ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฌธ๋ฒ
์ด๋ฅผ ์๋ฐ์คํฌ๋ฆฝํธ์ Promise ๊ฐ์ฒด๋ฅผ ์ด์ฉํด ๋ฆฌํฉํ ๋งํ๋ฉด, ๋น๋๊ธฐ ์์
์ ๊ฐ์๊ฐ ๋ง์์ ธ๋ ๋ค์ฌ์ฐ๊ธฐ ์ฝ๋์ ๊น์ด๊ฐ ๊น์ด์ง์ง ์๊ฒ ๋๋ค. ์์ง ํ๋ก๋ฏธ์ค ๋ฌธ๋ฒ์ ๋ํด ์ ๋ชจ๋ฅด์ง๋ง .then() ์ ํตํด ์ด๋ค์ ์ด๊ฑฐํ์ฌ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๊น๋ํ๊ฒ ํํํ์์ ๋ณผ ์ ์๋ค.
function increaseAndPrint(n) {
return new Promise((resolve, reject)=>{
setTimeout(() => {
const increased = n + 1;
console.log(increased);
resolve(increased);
}, 1000)
})
}
increaseAndPrint(0)
.then((n) => increaseAndPrint(n))
.then((n) => increaseAndPrint(n))
.then((n) => increaseAndPrint(n))
.then((n) => increaseAndPrint(n)); // ์ฒด์ด๋ ๊ธฐ๋ฒ
์ด์ฒ๋ผ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ก๋ฏธ์ค๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๊ทผ๊ฐ์ด ๋๋ ๊ธฐ๋ฒ ์ค ํ๋์ด๋ค. ํ๋ก๋ฏธ์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋ฐฑ ํจ์๋ฅผ ๋์ฒดํ๊ณ , ๋น๋๊ธฐ ์์ ์ ํ๋ฆ์ ์ฝ๊ฒ ์ ์ดํ ์ ์๋ค. ์ง๊ธ๋ถํฐ ์ด ์๋ฐ์คํฌ๋ฆฝํธ์ Promise ์ฌ์ฉ๋ฒ์ ๋ํด ์์๋ณด๋๋ก ํ์.
์๋ฐ์คํฌ๋ฆฝํธ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด
์๋ฐ์คํฌ๋ฆฝํธ Promise ๊ฐ์ฒด๋ ๋น๋๊ธฐ ์์ ์ ์ต์ข ์๋ฃ ๋๋ ์คํจ๋ฅผ ๋ํ๋ด๋ Array๋ Object ์ฒ๋ผ ๋ ์์ ์ธ ๊ฐ์ฒด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค. ๋น๋๊ธฐ ์์ ์ด ๋๋ ๋๊น์ง ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด ์๋๋ผ, ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ๊ฒ ๋ค๋ '์ฝ์'์ ๋ฐํํ๋ค๋ ์๋ฏธ์์ Promise๋ผ ๋ช ๋ช ์ง์ด์ก๋ค๊ณ ํ๋ค.
ํ๋ก๋ฏธ์ค ๊ฐ์ฒด ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
ํ๋ก๋ฏธ์ค ๊ฐ์ฒด ์์ฑ
Promise ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ค๋ฉด new ํค์๋์ Promise ์์ฑ์ ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ์ด๋ Promise ์์ฑ์ ์์ ๋๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฃ๊ฒ ๋๋๋ฐ, ์ฒซ ๋ฒ์งธ ์ธ์๋ ์์
์ด ์ฑ๊ณตํ์ ๋ ์ฑ๊ณต(resolve)์์ ์๋ ค์ฃผ๋ ๊ฐ์ฒด์ด๋ฉฐ, ๋ ๋ฒ์งธ ์ธ์๋ ์์
์ด ์คํจํ์ ๋ ์คํจ(reject)์์ ์๋ ค์ฃผ๋ ์ค๋ฅ ๊ฐ์ฒด์ด๋ค.
Promise ์์ฑ์์์ ๋ค์ด๊ฐ๋ ์ฝ๋ฐฑ ํจ์๋ฅผ executor ๋ผ๊ณ ๋ถ๋ฅธ๋ค.
const myPromise = new Promise((resolve, reject) => {
// ๋น๋๊ธฐ ์์
์ํ
const data = fetch('์๋ฒ๋ก๋ถํฐ ์์ฒญํ URL');
if(data)
resolve(data); // ๋ง์ผ ์์ฒญ์ด ์ฑ๊ณตํ์ฌ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด
else
reject("Error"); // ๋ง์ผ ์์ฒญ์ด ์คํจํ์ฌ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด
})
์ ์ฝ๋์์ ์๋ฒ๋ก๋ถํฐ ์์ฒญํ๋ ๋น๋๊ธฐ ์์
์ด ์ฑ๊ณตํ๋๋ ์คํจํ๋๋์ ๋ฐ๋ผ ๋งค๊ฐ๋ณ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ด ๋๋จ์ ๋ณผ ์ ์๋ค. ๋ง์ผ ์์
์ด ์ฑ๊ณตํ๋ค๋ฉด ๋น๋๊ธฐ ๋ก์ง ์คํ์ด ์ฐธ์ด๋ผ๋ ๊ฑธ ์๋ ค์ฃผ๊ธฐ ์ํด ๋ง ๊ทธ๋๋ก resolve() ์ฑ๊ณต ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค. ์คํจํ๋ฉด reject() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค. ๋ง์น ์ค์์น๋ฅผ ๋ด๋ ค ์ ๊ธฐ๋ฅผ ํ๋ฅด๊ฒ ํ๊ฑฐ๋ ์ฌ๋ ค์ ์ํ๋ฅด๊ฒ ํ๊ฑฐ๋ ๊ฐ์ ์๋ฆฌ์ด๋ค.
ํ๋ก๋ฏธ์ค ๊ฐ์ฒด ์ฒ๋ฆฌ
์ด๋ ๊ฒ ๋ง๋ค์ด์ง Promise ๊ฐ์ฒด๋ ๋น๋๊ธฐ ์์
์ด ์๋ฃ๋ ์ดํ์ ๋ค์ ์์
์ ์ฐ๊ฒฐ์์ผ ์งํํ ์ ์๋ค. ์์
๊ฒฐ๊ณผ ๋ฐ๋ผ .then() ๊ณผ .catch() ๋ฉ์๋ ์ฒด์ด๋์ ํตํด ์ฑ๊ณต๊ณผ ์คํจ์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ฅผ ์งํํ ์ ์๋ค.
๋ง์ผ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณตํ์ฌ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด ๋ด๋ถ์์ resolve(data) ๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด, ๋ฐ๋ก .then() ์ผ๋ก ์ด์ด์ ธ then ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์์์ ์ฑ๊ณต์ ๋ํ ์ถ๊ฐ ์ฒ๋ฆฌ๋ฅผ ์งํํ๋ค. ์ด๋ ํธ์ถํ resolve() ํจ์์ ๋งค๊ฐ๋ณ์์ ๊ฐ์ด then ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์ ์ธ์๋ก ๋ค์ด๊ฐ then ๋ฉ์๋ ๋ด๋ถ์์ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด ๋ด๋ถ์์ ๋ค๋ฃฌ ๊ฐ์ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
๋ฐ๋๋ก ์ฒ๋ฆฌ๊ฐ ์คํจํ์ฌ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด ๋ด๋ถ์์ reject("Error") ๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด, ๋ฐ๋ก .catch() ๋ก ์ด์ด์ ธ catch ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์์์ ์ฑ๊ณต์ ๋ํ ์ถ๊ฐ ์ฒ๋ฆฌ๋ฅผ ์งํํ๋ค.
myPromise
.then((value) => { // ์ฑ๊ณต์ ์ผ๋ก ์ํํ์ ๋ ์คํ๋ ์ฝ๋
console.log("Data: ", value); // ์์์ return resolve(data)์ data๊ฐ์ด ์ถ๋ ฅ๋๋ค
})
.catch((error) => { // ์คํจํ์ ๋ ์คํ๋ ์ฝ๋
console.error(error); // ์์์ return reject("Error")์ "Error"๊ฐ ์ถ๋ ฅ๋๋ค
})
.finally(() => { // ์ฑ๊ณตํ๋ ์คํจํ๋ ๋ฌด์กฐ๊ฑด ์คํ๋ ์ฝ๋
})
ํ๋ก๋ฏธ์ค ํจ์ ๋ฑ๋ก
์์ ๊ฐ์ด ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ณ์์ ๋ฐ๋ก ํ ๋นํ๋ ๋ฐฉ์์ ์ฌ์ฉํ ์๋ ์์ง๋ง, ๋ณดํต์ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๋๋ก ํจ์๋ก ๊ฐ์ธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
// ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์ ์์ฑ
function myPromise() {
return new Promise((resolve, reject) => {
if (/* ์ฑ๊ณต ์กฐ๊ฑด */) {
resolve(/* ๊ฒฐ๊ณผ ๊ฐ */);
} else {
reject(/* ์๋ฌ ๊ฐ */);
}
});
}
// ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์ ์ฌ์ฉ
myPromise()
.then((result) => {
// ์ฑ๊ณต ์ ์คํํ ์ฝ๋ฐฑ ํจ์
})
.catch((error) => {
// ์คํจ ์ ์คํํ ์ฝ๋ฐฑ ํจ์
});
ํจ์๋ฅผ ๋ง๋ค๊ณ ๊ทธ ํจ์๋ฅผ ํธ์ถํ๋ฉด ํ๋ก๋ฏธ์ค ์์ฑ์๋ฅผ return ํจ์ผ๋ก์, ๊ณง๋ฐ๋ก ์์ฑ๋ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์ ๋ฐํ๊ฐ์ผ๋ก ์ป์ด ์ฌ์ฉํ๋ ๊ธฐ๋ฒ์ด๋ค. ์ด๋ ๊ฒ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์๋ก ๋ง๋๋ ์ด์ ๋ ๋ค์ 3๊ฐ์ง ์ ๋๊ฐ ์๋ค.
- ์ฌ์ฌ์ฉ์ฑ : ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์๋ก ๋ง๋ค๋ฉด ํ์ํ ๋๋ง๋ค ํธ์ถํ์ฌ ์ฌ์ฉํจ์ผ๋ก์จ, ๋ฐ๋ณต๋๋ ๋น๋๊ธฐ ์์ ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
- ๊ฐ๋ ์ฑ : ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์๋ก ๋ง๋ค๋ฉด ์ฝ๋์ ๊ตฌ์กฐ๊ฐ ๋ช ํ์ ธ, ๋น๋๊ธฐ ์์ ์ ์ ์์ ์ฌ์ฉ์ ๋ถ๋ฆฌํ์ฌ ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์๋ค.
- ํ์ฅ์ฑ : ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์๋ก ๋ง๋ค๋ฉด ์ธ์๋ฅผ ์ ๋ฌํ์ฌ ๋์ ์ผ๋ก ๋น๋๊ธฐ ์์ ์ ์ํํ ์ ์๋ค. ๋ํ ์ฌ๋ฌ ๊ฐ์ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์๋ค์ ์ฐ๊ฒฐํ์ฌ ๋ณต์กํ ๋น๋๊ธฐ ๋ก์ง์ ๊ตฌํํ ์ ์๋ค.
ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑํ์ฌ ๋ฐํํ๋ ํจ์๋ฅผ 'ํ๋ก๋ฏธ์ค ํฉํ ๋ฆฌ ํจ์' ๋ผ๊ณ ๋ถ๋ฆฌ์ฐ๊ธฐ๋ ํ๋ค.
์ด๋ฌํ ์ ๋๋ฌธ์ ์ค๋ฌด์์ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ผ์ด ์๋ค๋ฉด ํจ์๋ก ๊ฐ์ธ ์ฌ์ฉํ๋ค. ๊ทธ๋์ ๋๋ถ๋ถ์ ์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํจ์ ํํ๋ก ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ค. ๋ํ์ ์ผ๋ก ์๋ฐ์คํฌ๋ฆฝํธ์ fetch() ๋ฉ์๋๊ฐ ์๋๋ฐ, ์ด fetch() ๋ฉ์๋ ๋ด์์ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ฉด resolve() ํ์ฌ .then() ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ด๋ค.
// GET ์์ฒญ ์์
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => response.json()) // ์๋ต ๊ฐ์ฒด์์ JSON ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ค.
.then((data) => console.log(data)); // JSON ๋ฐ์ดํฐ๋ฅผ ์ฝ์์ ์ถ๋ ฅํ๋ค.
ํ๋ก๋ฏธ์ค 3๊ฐ์ง ์ํ
ํ๋ก๋ฏธ์ค๋ ๋น๋๊ธฐ ์์
์ ๊ฒฐ๊ณผ๋ฅผ ์ฝ์ํ๋ ๊ฒ์ด๋ค. new Promise() ์์ฑ์๋ก ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉด, ๊ทธ ๋น๋๊ธฐ ์์
์ ์ด๋ฏธ ์งํ ์ค์ด๊ณ ์ธ์ ๊ฐ๋ ์ฑ๊ณตํ๊ฑฐ๋ ์คํจํ ๊ฒ์ด๋ค. ์ด๋ฌํ ์งํ์ค, ์ฑ๊ณต, ์คํจ ์ํ๋ฅผ ๋ํ๋ด๋ ๊ฒ์ด ๋ฐ๋ก ํ๋ก๋ฏธ์ค์ ์ํ(state)๋ผ๊ณ ๋ถ๋ฆฌ์ด๋ค. ์ฝ๊ฒ ๋งํ์๋ฉด ์ผ์ข
์ ํ๋ก๋ฏธ์ค ์ฒ๋ฆฌ ๊ณผ์ ์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
- Pending(๋๊ธฐ) : ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋์ง ์์ ์ํ (์ฒ๋ฆฌ ์งํ์ค)
- Fulfilled(์ดํ) : ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋ ์ํ
- Eejected(๊ฑฐ๋ถ) : ์ฒ๋ฆฌ๊ฐ ์คํจ๋ก ๋๋ ์ํ

1. Pending ์ํ
๋๊ธฐ(pending) ์ํ๋, ๋ง ๊ทธ๋๋ก ์์ง ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ก์ง์ด ์๋ฃ ๋์ง ์์ ์ํ์ด๋ค. ์๋ฅผ ๋ค์ด ์๋์ ๊ฐ์ด ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ์์ฑํ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์ฝ์์ ์ฐ์ด๋ณด๋ฉด ์๋์ ๊ฐ์ด ํ๋ก๋ฏธ์ค ๊ฐ์ฒด์ ์ํ๊ฐ "pending"์ผ๋ก ์ถ๋ ฅ๋๊ฒ ๋๋ค.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("์ฒ๋ฆฌ ์๋ฃ")
}, 5000)
});
console.log(promise); // Pending (๋๊ธฐ) ์ํ

2. Fulfilled ์ํ
์์ ํ๋ก๋ฏธ์ค ์ฝ๋๋ฅผ ์คํํ๊ณ 5์ด ๋์ ๊ธฐ๋ค๋ฆฌ๋ค๊ฐ ๋ค์ ์ฝ์์ ์ฐ์ด๋ณด์. ๊ทธ๋ผ ์๋์ ๊ฐ์ด ์ดํ(fulfilled) ์ํ๋ก ๋ณํ๊ฒ ๋๋ค.

์ฆ, 5์ด๊ฐ ์ง๋ resolve() ์ํ๋๋ฉด์ ํ๋ก๋ฏธ์ค ์ฑ๊ณต์ ์๋ฆฌ๋ ๊ฐ์ฒด๋ฅผ ํธ์ถ ํ์์ผ๋ ์ดํ ์ํ๋ก ๋ณํ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ ์ดํ(fulfilled) ์ํ๋, ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ก์ง์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ ๋ฌ๋ค๋ ๊ฒ์ ํํํ๊ธฐ ์ํ ์ํ๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.

ํ๋ก๋ฏธ์ค์ '์ดํ' ์ํ๋ฅผ ๋ค๋ฅด๊ฒ ํํํ์๋ฉด '์๋ฃ' ๋ด๋ ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ดํ ์ํ๋ก ๋ณํ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ ๋ฐ๋ก ์ฒด์ด๋๋ .then() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐ์ ์ ์๋ ๊ฒ์ด๋ค.
promise
.then((data) => {
console.log("ํ๋ก๋ฏธ์ค๊ฐ ์ดํ ์ํ๊ฐ ๋๋ฉด์ ์ฒ๋ฆฌ์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ์ํ")
})
3. Rejected ์ํ
resolve()๋ฅผ ํธ์ถํจ์ผ๋ก์ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด ์ํ๊ฐ ์ดํ(fulfilled) ์ํ๊ฐ ๋ฌ๋ค๋ฉด, ๋ฐ๋๋ก reject()๋ฅผ ํธ์ถํ๋ฉด ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๊ฐ ์คํจ(rejected) ์ํ๊ฐ ๋๋ค.

const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject("์ฒ๋ฆฌ ์คํจ")
}, 5000)
});

์ญ์ ์คํจ ์ํ๋ก ๋ณํ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ ๋ฐ๋ก ์ฒด์ด๋๋ .catch() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ฒ๋ฆฌ ์คํจ์ ๋ํ ํ๋์ ์ํํ๊ฒ ๋๋ค.
promise
.catch((error) => {
console.log(error);
console.log("์คํจ์ ๋ํ ํ์ ์กฐ์น...")
})
ํ๋ก๋ฏธ์ค ํธ๋ค๋ฌ
ํ๋ก๋ฏธ์ค๊ฐ ์์ฑ๋๋ฉด, ๊ทธ ์์
์ ์ด๋ฏธ ์งํ ์ค์ด๊ณ ์ธ์ ๊ฐ๋ ์ฑ๊ณตํ๊ฑฐ๋ ์คํจํ ๊ฒ์ด๋ค. ๊ทธ ์ฑ๊ณต/์คํจ ๊ฒฐ๊ณผ๋ฅผ .then / .catch / .finally ํธ๋ค๋ฌ๋ฅผ ํตํด ๋ฐ์ ๋ค์ ํ์ ์์
์ ์ํํ ์ ์๋ค. ํ๋ก๋ฏธ์ค ํธ๋ค๋ฌ๋ ํ๋ก๋ฏธ์ค์ ์ํ์ ๋ฐ๋ผ ์คํ๋๋ ์ฝ๋ฐฑ ํจ์๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
.then(): ํ๋ก๋ฏธ์ค๊ฐ ์ดํ(fulfilled)๋์์ ๋ ์คํํ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฑ๋กํ๊ณ , ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํ.catch(): ํ๋ก๋ฏธ์ค๊ฐ ๊ฑฐ๋ถ(rejected)๋์์ ๋ ์คํํ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฑ๋กํ๊ณ , ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํ.finally(): ํ๋ก๋ฏธ์ค๊ฐ ์ดํ๋๊ฑฐ๋ ๊ฑฐ๋ถ๋ ๋ ์๊ด์์ด ์คํํ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฑ๋กํ๊ณ , ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํ
ํ๋ก๋ฏธ์ค ํธ๋ค๋ฌ ๊ตฌ์ฑ์ ๋ณด๊ฑด๋ฐ, ๋ง์น try - catch - finally ๊ตฌ์กฐ์ ๊ต์ฅํ ์ ์ฌํ๋ค๊ณ ๋๋ํ
๋ฐ ๊ทธ ๋๋์ด ๋ง๋ค.
์ด๋ฏธ ์์์ ํ๋ก๋ฏธ์ค ์ํ์ ๋ฐ๋ผ ์ํ๋๋ ํ๋ก๋ฏธ์ค ํธ๋ค๋ฌ ๋ฌธ๋ฒ์ ๋ํด ๋ค๋ค์ผ๋ ๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ๋ฒ์ ๋ค๋ค ์ ๊ฒ์ด๋ค. ๋ค๋ง ์ด ์น์ ์์ ์๊ฐํ๊ณ ์ถ์ ๊ฒ์ ์ด ํธ๋ค๋ฌ๋ค์ ์ฒด์ด๋(chaining) ํ์ฌ ์ด๊ฑฐํ์ฌ ๋ณต์กํ๊ฒ ์ฌ์ฉํ ๋ ์ฒ๋ฆฌ ์์์ ๋ํ ๋ถ๋ถ์ด๋ค.
ํ๋ก๋ฏธ์ค ์ฒด์ด๋
ํ๋ก๋ฏธ์ค ์ฒด์ด๋์ด๋, ํ๋ก๋ฏธ์ค ํธ๋ค๋ฌ๋ฅผ ์ฐ๋ฌ์ ์ฐ๊ฒฐํ๋ ๊ฒ์ ๋งํ๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์์ ์ ์์ฐจ์ ์ผ๋ก ์ํํ ์ ์๋ค๋ ํน์ง์ด ์๋ค.
์๋ฅผ๋ค์ด ์๋๋ doSomething ํจ์๋ฅผ ํธ์ถํ์ฌ ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑํ๊ณ , then ๋ฉ์๋๋ฅผ ํตํด ์ดํ ํธ๋ค๋ฌ๋ฅผ ์ฐ๊ฒฐํ๋ ๊ณผ์ ์ ๋ณด์ฌ์ค๋ค. ๊ฐ ์ดํ ํธ๋ค๋ฌ๋ ์ด์ ํ๋ก๋ฏธ์ค์ ๊ฐ์ 50์ ๋ํ ๊ฐ์ ๋ฐํํ๊ณ , ๋ง์ง๋ง ์ดํ ํธ๋ค๋ฌ๋ ์ต์ข
๊ฐ์ ์ฝ์์ ์ถ๋ ฅํ๊ฒ ๋๋ค.
function doSomething() {
return new Promise((resolve, reject) => {
resolve(100)
});
}
doSomething()
.then((value1) => {
const data1 = value1 + 50;
return data1
})
.then((value2) => {
const data2 = value2 + 50;
return data2
})
.then((value3) => {
const data3 = value3 + 50;
return data3
})
.then((value4) => {
console.log(value4); // 250 ์ถ๋ ฅ
})

์ด๋ฐ์์ผ๋ก ์ฒด์ด๋์ด ๊ฐ๋ฅํ ์ด์ ๋ then ํธ๋ค๋ฌ์์ ๊ฐ์ ๋ฆฌํดํ๋ฉด, ๊ทธ ๋ฐํ๊ฐ์ ์๋์ผ๋ก ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ก ๊ฐ์ธ์ ธ ๋ฐํ๋๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค์ then ํธ๋ค๋ฌ์์ ๋ฐํ๋ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด๋ค. ๊ทธ๋์ ํ๋ก๋ฏธ์ค ์ํ์ ํ๋ฆ๋๋ฅผ ํํํ์๋ฉด ์๋์ ๊ฐ์ด ๋๋ค.

๋ง์ผ ์ฐ๊ฒฐ๋ ์ดํ ํธ๋ค๋ฌ์์ ์ค๊ฐ์ ์ค๋ฅ๊ฐ ์๋ ์ฒ๋ฆฌ๋ฅผ ํํ๋ค๋ฉด ์์ธ์ฒ๋ฆฌ๋ฅผ ํจ์ผ๋ก์จ catch ํธ๋ค๋ฌ์ ์ ํํ๋๋ก ์ค์ ํ ์ ์๋ค. ์ด๋ ต๊ฒ ์๊ฐํ์ง ๋ง๊ณ try - catch ์ ๊ฐ์ด ์๊ฐํ๋ฉด ๋๋ค.
function doSomething(arg) {
return new Promise((resolve, reject) => {
resolve(arg)
});
}
doSomething('100A')
.then((value1) => {
const data1 = value1 + 50; // ์ซ์์ ๋ฌธ์๋ฅผ ์ฐ์ฐ
if (isNaN(data1))
throw new Error('๊ฐ์ด ๋๋ฒ๊ฐ ์๋๋๋ค')
return data1
})
.then((value2) => {
const data2 = value2 + 50;
return data2
})
.catch((err) => {
console.error(err);
})

๋ง์ผ catch ํธ๋ค๋ฌ ๋ค์์ผ๋ก then ํธ๋ค๋ฌ๊ฐ ์ด์ด์ ์ฒด์ด๋ ๋์ด ์๋ค๋ฉด, ์๋ฌ๊ฐ ์ฒ๋ฆฌ๋๊ณ ๊ฐ๊น์ด then ํธ๋ค๋ฌ๋ก ์ ์ด ํ๋ฆ์ด ๋์ด๊ฐ ์คํ์ด ์ด์ด์ง๊ฒ ๋๋ค.
new Promise((resolve, reject) => {
throw new Error("์๋ฌ ๋ฐ์!");
})
.catch(function(error) {
console.log("์๋ฌ๊ฐ ์ ์ฒ๋ฆฌ๋์์ต๋๋ค. ์ ์์ ์ผ๋ก ์คํ์ด ์ด์ด์ง๋๋ค.");
})
.then(() => {
console.log("๋ค์ ํธ๋ค๋ฌ๊ฐ ์คํ๋ฉ๋๋ค.")
})
.then(() => {
console.log("๋ค์ ํธ๋ค๋ฌ๊ฐ ๋ ์คํ๋ฉ๋๋ค.")
});

ํ๋ก๋ฏธ์ค ์ ์ ๋ฉ์๋
ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ ์์ฑ์ ํจ์ ์ธ์๋ ์ฌ๋ฌ ๊ฐ์ง ์ ์ ๋ฉ์๋(static method)๋ฅผ ์ ๊ณตํ๋ค. ์ ์ ๋ฉ์๋๋ ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํ & ์์ฑํ์ง ์๊ณ ๋ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ณด๋ค ํจ์จ์ ์ด๊ณ ๊ฐํธํ๊ฒ ๊ตฌํํ ์ ์๋๋ก ๋์์ค๋ค.
Promise.resolve()
๋ณดํต ํ๋ก๋ฏธ์ค์ resolve() ๋ฉ์๋๋, ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑ์๋ก ๋ง๋ค๊ณ ๊ทธ์์ ์ฝ๋ฐฑ ํจ์์ ๋งค๊ฐ๋ณ์๋ฅผ ํตํด ํธ์ถํ์ฌ ์ฌ์ฉํด์๋ค.
// ํ๋ก๋ฏธ์ค ์์ฑ์๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์
function getPromiseNumber() {
return new Promise((resolve, reject) => {
const num = Math.floor(Math.random() * 10); // 0 ~ 9 ์ฌ์ด์ ์ ์
resolve(num); // ํ๋ก๋ฏธ์ค ์ดํ
});
}
์ด๋ฌํ ๊ณผ์ ์ Promise.resolve() ์ ์ ๋ฉ์๋๋ก ํ๋ฒ์ ํธ์ถํ ์ ์๋๋ก ํธ์ ๊ธฐ๋ฅ์ ์ ๊ณตํด ์ฃผ๋ ๊ฒ์ผ๋ก ๋ณด๋ฉด ๋๋ค. ๊ทธ๋์ ํ๋ก๋ฏธ์ค ์ ์ ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ฉด ํ๋ก๋ฏธ์ค ๊ฐ์ฒด์ ์ ํ ์ฐ๊ด์๋ ํจ์ ๋ด์์ ํ์์ ๋ฐ๋ผ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ์ฌ ํธ๋ค๋ฌ๋ฅผ ์ด์ฉํ ์ ์๋๋ก ์์ฉ์ด ๊ฐ๋ฅํ๋ค. ์ด ๋ฐฉ๋ฒ์ ๋น๋๊ธฐ ์์
์ ์ํํ์ง ์๋ ํจ์์์๋ ํ๋ก๋ฏธ์ค์ ์ฅ์ ์ ํ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ์ ์ ์ฉํ๋ค.
// ํ๋ก๋ฏธ์ค ๊ฐ์ฒด์ ์ ํ ์ฐ๊ด์๋ ํจ์
function getRandomNumber() {
const num = Math.floor(Math.random() * 10); // 0 ~ 9 ์ฌ์ด์ ์ ์
return num;
}
// Promise.resolve() ๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์
function getPromiseNumber() {
const num = getRandomNumber(); // ์ผ๋ฐ ๊ฐ
return Promise.resolve(num); // ํ๋ก๋ฏธ์ค ๊ฐ์ฒด
}
// ํธ๋ค๋ฌ๋ฅผ ์ด์ฉํ์ฌ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด์ ๊ฐ์ ์ฒ๋ฆฌํ๋ ํจ์
getPromiseNumber()
.then((value) => {
console.log(`๋๋ค ์ซ์: ${value}`);
})
.catch((error) => {
console.error(error);
});
Promise.reject()
๋ง์ฐฌ๊ฐ์ง๋ก ์ฃผ์ด์ง ์ฌ์ ๋ก ๊ฑฐ๋ถํ๋ Promise ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
// ์ฃผ์ด์ง ์ฌ์ ๋ก ๊ฑฐ๋ถ๋๋ ํ๋ก๋ฏธ์ค ์์ฑ
const p = Promise.reject(new Error('error'));
// ๊ฑฐ๋ถ ์ฌ์ ๋ฅผ ์ถ๋ ฅ
p.catch(error => console.error(error)); // Error: error
Promise.all()
๋ฐฐ์ด, Map, Set์ ํฌํจ๋ ์ฌ๋ฌ๊ฐ์ ํ๋ก๋ฏธ์ค ์์๋ค์ ํ๊บผ๋ฒ์ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํด์ผ ํ ๋ ๊ต์ฅํ ์ ์ฉํ ํ๋ก๋ฏธ์ค ์ ์ ๋ฉ์๋์ด๋ค. ๋ชจ๋ ํ๋ก๋ฏธ์ค ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ดํ(fulfilled) ๋ ๋๊น์ง ๊ธฐ๋ค๋ ค์, ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ ์๋ฃ๋๋ฉด ๊ทธ๋ then ํธ๋ค๋ฌ๊ฐ ์คํํ๋ ํํ๋ก ๋ณด๋ฉด ๋๋ค. ๊ฐ์ฅ ๋ํ์ ์ธ ์ฌ์ฉ ์์๋ก ์ฌ๋ฌ ๊ฐ์ API ์์ฒญ์ ๋ณด๋ด๊ณ ๋ชจ๋ ์๋ต์ ๋ฐ์์ผ ํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ ์ ์๋ค.
// 1. ์๋ฒ ์์ฒญ API ํ๋ก๋ฏธ์ค ๊ฐ์ฒด ์์ฑ (fetch)
const api_1 = fetch("https://jsonplaceholder.typicode.com/users");
const api_2 = fetch("https://jsonplaceholder.typicode.com/users");
const api_3 = fetch("https://jsonplaceholder.typicode.com/users");
// 2. ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ค์ ๋ฌถ์ด ๋ฐฐ์ด๋ก ๊ตฌ์ฑ
const promises = [api_1, api_2, api_3];
// 3. Promise.all() ๋ฉ์๋ ์ธ์๋ก ํ๋ก๋ฏธ์ค ๋ฐฐ์ด์ ๋ฃ์ด, ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ ์ดํ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ณ , ๊ฒฐ๊ณผ๊ฐ์ ์ถ๋ ฅ
Promise.all(promises)
.then((results) => {
// results๋ ์ดํ๋ ํ๋ก๋ฏธ์ค๋ค์ ๊ฐ๋ค์ ๋ด์ ๋ฐฐ์ด.
// results์ ์์๋ promises์ ์์์ ์ผ์น.
console.log(results); // [users1, users2, users3]
})
.catch((error) => {
// ์ด๋ ํ๋๋ผ๋ ํ๋ก๋ฏธ์ค๊ฐ ๊ฑฐ๋ถ๋๋ฉด ์ค๋ฅ๋ฅผ ์ถ๋ ฅ
console.error(error);
});
Promise.allSettled()
Promise.all() ๋ฉ์๋์ ์
๊ทธ๋ ์ด๋ ๋ฒ์ ์ผ๋ก, ์ฃผ์ด์ง ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ ์ฒ๋ฆฌ๋๋ฉด ๋ชจ๋ ํ๋ก๋ฏธ์ค ๊ฐ๊ฐ์ ์ํ์ ๊ฐ (๋๋ ๊ฑฐ๋ถ ์ฌ์ )์ ๋ชจ์๋์ ๋ฐฐ์ด์ ๋ฐํํ๋ค.
๐ Promise.allSettled ์ Promise.all ๋น๊ต ์ ๋ฆฌ
Promise.all ์ ๋ฌธ์ ์ Promise.all([ promise1, promise2, ... ]) ์ ํํ๋ก ์ฌ์ฉ๋๋ฉฐ, ๋ฐฐ์ด๋ก ๋ฐ์ ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ fulfill ๋ ์ดํ, ๋ชจ๋ ํ๋ก๋ฏธ์ค์ ๋ฐํ ๊ฐ์ ๋ฐฐ์ด์ ๋ฃ์ด ๋ฐํํ๋ค. ๊ทธ๋ฐ๋ฐ ๋ง์ฝ ๋ฐฐ์ด์ ์๋
inpa.tistory.com
// 1์ด ํ์ 1์ ๋ฐํํ๋ ํ๋ก๋ฏธ์ค
const p1 = new Promise(resolve => setTimeout(() => resolve(1), 1000));
// 2์ด ํ์ ์๋ฌ๋ฅผ ๋ฐ์์ํค๋ ํ๋ก๋ฏธ์ค
const p2 = new Promise((resolve, reject) => setTimeout(() => reject(new Error('error')), 2000));
// 3์ด ํ์ 3์ ๋ฐํํ๋ ํ๋ก๋ฏธ์ค
const p3 = new Promise(resolve => setTimeout(() => resolve(3), 3000));
// ์ธ ๊ฐ์ ํ๋ก๋ฏธ์ค์ ์ํ์ ๊ฐ ๋๋ ์ฌ์ ๋ฅผ ์ถ๋ ฅ
Promise.allSettled([p1, p2, p3])
.then(result => console.log(result));

Promise.any()
Promise.all() ๋ฉ์๋์ ๋ฐ๋ ๋ฒ์ ์ผ๋ก, Promise.all() ์ด ์ฃผ์ด์ง ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ ๋ชจ๋ ์๋ฃํด์ผ๋ง ๊ฒฐ๊ณผ๋ฅผ ๋์ถํ๋ค๋ฉด, Promise.any() ๋ ์ฃผ์ด์ง ๋ชจ๋ ํ๋ก๋ฏธ์ค ์ค ํ๋๋ผ๋ ์๋ฃ๋๋ฉด ๋ฐ๋ก ๋ฐํํ๋ ์ ์ ๋ฉ์๋์ด๋ค.
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("promise1 failed");
}, 3000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("promise2 succeeded");
}, 2000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("promise3 failed");
}, 1000);
});
// promise1, promise2, promise3์ ๊ฐ๊ฐ 3์ด, 2์ด, 1์ด ํ์ ๊ฑฐ๋ถ๋๊ฑฐ๋ ์ดํ
Promise.any([promise1, promise2, promise3])
.then((value) => {
console.log(value); // "promise2 succeeded"
})
.catch((error) => {
console.error(error);
});
์ ์ฝ๋๋ฅผ ๋ณด๋ฉด Promise.any() ๋ฉ์๋์ ๊ฒฐ๊ณผ๋ก promise2์ ์ฒ๋ฆฌ๊ฐ ๊ฐ์ฅ ๋จผ์ ๋์ถ๋จ์ ๋ณผ ์ ์๋ค. ์ค๋ก์ง ์ฒซ๋ฒ์งธ๋ก ์ดํ(fulfilled) ๋ ํ๋ก๋ฏธ์ค๋ง์ ์ทจ๊ธํ๊ธฐ ๋๋ฌธ์ ๋๋จธ์ง promise1๊ณผ promise3์ ๊ฑฐ๋ถ(rejected)๋ ๋ฌด์๋๊ฒ ๋๋ค.
๋ง์ผ ์์ฒญ๋ ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ ๊ฑฐ๋ถ(rejected)๋๋ฉด, AggregateError ๊ฐ์ฒด๋ฅผ ์ฌ์ ๋ก ํ๋ ๊ฑฐ๋ถ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("promise1 failed");
}, 3000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("promise2 succeeded");
}, 2000);
});
const promise4 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("promise4 failed");
}, 4000);
});
Promise.any([promise1, promise3, promise4])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error); // AggregateError: All promises were rejected
console.error(error.errors); // ["promise3 failed", "promise1 failed", "promise4 failed"]
});
Promise.race()
Promise.race() ๋ Promise.any() ์ ๊ฐ์ด ์ฌ๋ฌ ๊ฐ์ ํ๋ก๋ฏธ์ค ์ค ๊ฐ์ฅ ๋จผ์ ์ฒ๋ฆฌ๋ ํ๋ก๋ฏธ์ค์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ์ง๋ง, ์ฐจ์ด์ ์ด ์กด์ฌํ๋ค.
Promise.any()๋ ๊ฐ์ฅ ๋จผ์ fulfilled(์ดํ) ์ํ๊ฐ ๋ ํ๋ก๋ฏธ์ค๋ง์ ๋ฐํํ๊ฑฐ๋, ํน์ ์ ๋ถ rejected(์คํจ) ์ํ๊ฐ๋ ํ๋ก๋ฏธ์ค(AggregateError)๋ฅผ ๋ฐํํ๋ค. ๋ฐ๋ฉด Promise.race() ๋ fulfilled(์ดํ), rejected(์คํจ) ์ฌ๋ถ ์๊ด์์ด ๋ฌด์กฐ๊ฑด ์ฒ๋ฆฌ๊ฐ ๋๋ ํ๋ก๋ฏธ์ค ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ๋ค.
๋ง์น ํ๋ก๋ฏธ์ค ์ฐธ๊ฐ์๋ค์ด ๋ ์ด์ฑ(race) ๊ฒฝ์ฃผ๋ฅผ ํ๋๊ฒ์ ๋ ์ฌ๋ฆฌ๋ฉด ๋๋ค.
์๋ ์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์ข ๋ ์ดํด๊ฐ ์์ํ ๊ฒ์ด๋ค.


์ฝ๋ฐฑ ์ง์ฅ์ ์ด์ ํ๋ก๋ฏธ์ค ์ง์ฅ
์๋ฐ์คํฌ๋ฆฝํธ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์ฒ์ ์๊ฐํ ๋ ์ฝ๋ฐฑ ์ง์ฅ์ ๊ทน๋ณตํ๋ ์ ์ธ๋์ ๋ฌธ๋ฒ์ด๋ผ๊ณ ์์ ์๊ฒ ์๊ฐํ์์ผ๋ฉด์ ์ฝ๋ฐฑ ์ง์ฅ์ ์ด์ ํ๋ก๋ฏธ์ค ์ง์ฅ(Promise Hell)์ด๋ผ๋ ํ ์์๋ง ๋์ฌ ๊ฒ์ด๋ค. ๊ทธ๋ฐ๋ฐ ์ฝ๋ฐฑ ๋ชป์ง์๊ฒ ํ๋ก๋ฏธ์ค์ then() ๋ฉ์๋๊ฐ ์ง๋์น๊ฒ ์ฒด์ธ๋์ด ๋ฐ๋ณต๋๋ฉด ์ฝ๋๊ฐ ์ฅํฉํด์ง๊ณ ๊ฐ๋
์ฑ์ด ๊ต์ฅํ ๋จ์ด์ง ์ ๊ฐ ์๋ค.
์๋ ์์ ์ฝ๋๋ fetch ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๊นํ๋ธ API์์ ์ ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ณ , then ๋ฉ์๋๋ฅผ ์ฌ๋ฌ ๋ฒ ์ฐ๊ฒฐํ์ฌ ์ ์ ๋ค์ ๋ก๊ทธ์ธ ์ด๋ฆ์ ์ผํ๋ก ๊ตฌ๋ถํ ๋ฌธ์์ด๋ก ๋ง๋ค์ด ์ถ๋ ฅํ๋ ๋น๋๊ธฐ ์์ ์ ์ํํ๋ค. ๋์ ์์ฒด๋ ๋ฌธ์ ๊ฐ ์์ ํ ์ง๋ง, ์ด๋ฐ์์ผ๋ก then์ ๋์ด๋จ์ด ๋์ผ๋ฉด ์ฝ๋๊ฐ ๊ธธ์ด์ง๊ณ , ๊ฐ then ๋ฉ์๋๊ฐ ์ด๋ค ๊ฐ์ ๋ฐํํ๋์ง ํ์ ํ๊ธฐ ์ด๋ ต๊ฒ ๋๋ค. ๋ํ, catch ๋ฉ์๋๊ฐ ๋ง์ง๋ง์ ํ ๋ฒ๋ง ์ฌ์ฉ๋์ด ์๊ธฐ ๋๋ฌธ์, ์ค๊ฐ์ ๋ฐ์ํ ์ ์๋ ์๋ฌ๋ ์์ธ ์ํฉ์ ๋์ํ๊ธฐ ์ด๋ ต๋ค.
fetch("https://api.github.com/users")
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error("Network Error");
}
})
.then((users) => {
return users.map((user) => user.login);
})
.then((logins) => {
return logins.join(", ");
})
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error(error);
});
์ด๋ฅผ ๋๋ค์ ๊ทน๋ณตํ๊ธฐ ์ํด ๋์จ ์๋ฐ์คํฌ๋ฆฝํธ์ ์ ์ธ๋ ๋ฌธ๋ฒ์ด ์๋๋ฐ ๋ฐ๋ก async/await ํค์๋์ด๋ค. async/await ํค์๋๋ ES8์์ ๋์ ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋ฌธ๋ฒ์ผ๋ก, ํ๋ก๋ฏธ์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ง๋ง then๊ณผ catch ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋น๋๊ธฐ ์์ ์ ์ํํ ์ ์๋ค. async/await ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋น๋๊ธฐ ์์ ์ ๋ง์น ๋๊ธฐ ์์ ์ฒ๋ผ ์ธ ์ ์์ด์ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํ๊ณ ๊ฐ๋ ์ฑ์ด ์ข์์ง๊ฒ ๋๋ค.
try {
const response = await fetch("");
if (response.ok) {
const users = await response.json();
const logins = users.map((user) => user.login);
const result = logins.join(", ");
console.log(result);
} else {
throw new Error("Network Error");
}
} catch (error) {
console.error(error);
}
์ ์ ์๋ ํ๋ก๋ฏธ์ค ํธ๋ค๋ฌ๋ฅผ ์์ ๋ฒ๋ฆฌ๊ณ 1 ๋ผ์ธ์ผ๋ก ๋น๋๊ธฐ ์ฝ๋๋ค์ ๊ตฌ์ฑํ์์ ๋ณผ ์ ์๋ค. async/await ๋ฌธ๋ฒ์ ๋ํด์ ์์ธํ ์ฌ์ฉ๋ฒ์ ์๋ ํฌ์คํ ์ ์ฐธ๊ณ ํ๊ธธ ๋ฐ๋๋ค.
๐ ์๋ฐ์คํฌ๋ฆฝํธ Async/Await ๊ฐ๋ & ๋ฌธ๋ฒ ์ ๋ณต
๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฐฉ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ฑ๊ธ ์ค๋ ๋ ํ๋ก๊ทธ๋๋ฐ์ธ์ด๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ์ฒ๋ฆฌ๊ฐ ํ์์ ์ด๋ค. ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ ๊ทธ ๊ฒฐ๊ณผ๊ฐ ์ธ์ ๋ฐํ๋ ์ง ์์ ์๊ธฐ ๋๋ฌธ์ ๋๊ธฐ์์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ธฐ๋ฒ๋ค์ด
inpa.tistory.com
# ์ฐธ๊ณ ์๋ฃ
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://ko.javascript.info/promise-basics
https://velog.io/@ljinsk3/JavaScript-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-Promise-%EA%B0%9D%EC%B2%B4
์ด ๊ธ์ด ์ข์ผ์ จ๋ค๋ฉด ๊ตฌ๋ & ์ข์์
์ฌ๋ฌ๋ถ์ ๊ตฌ๋
๊ณผ ์ข์์๋
์ ์์๊ฒ ํฐ ํ์ด ๋ฉ๋๋ค.