- Javascript ์์๋ ๋๋ถ๋ถ์ ์์ ๋ค์ด ๋น๋๊ธฐ๋ก ์ด๋ฃจ์ด์ง๋ค.
- ์ฝ๋ฐฑ ํจ์๋ก ์ฒ๋ฆฌํ๋ฉด ๋๋ ๋ฌธ์ ์์ง๋ง ์์ฆ์๋ ํ๋ก ํธ์๋์ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด์ ์ฝ๋์ ๋ณต์ก๋๊ฐ ๋์์ง๋ ์ํฉ์ด ๋ฐ์ํ์๋ค. ์ด์ ์ฝ๋ฐฑ์ด ์ค์ฒฉ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ๋ผ์ ๋ฐ์ํ์๊ณ , ์ด๋ฅผ ํด๊ฒฐํ ๋ฐฉ์์ผ๋ก ๋ฑ์ฅํ ๊ฒ์ด Promise ํจํด์ด๋ค.
- Promise ํจํด์ ์ฌ์ฉํ๋ฉด ๋น๋๊ธฐ ์์ ๋ค์ ์์ฐจ์ ์ผ๋ก ์งํํ๊ฑฐ๋, ๋ณ๋ ฌ๋ก ์งํํ๋ ๋ฑ์ ์ปจํธ๋กค์ด ๋ณด๋ค ์์ํด์ง๋ค.
- promise๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ชฉ์ ์ผ๋ก ์ ๊ณต๋๋ ์๋ฐ์คํฌ๋ฆฝํธ ๋ด์ฅ ๊ฐ์ฒด์ด๋ค.
const promise = new Promise(์คํ ํจ์);
- ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ณ์์ธ promise์ ์ ์ฅํจ
- ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ง๋ค ๋ ์ธ์๋ก ์คํ ํจ์(executor)๋ฅผ ์ ๋ฌํจ.
- ์คํ ํจ์ : ๋น๋๊ธฐ ์์ ์ ์ํํ๋ ํจ์์ด๋ค.
- ์ด ํจ์๋ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์์ฑ๊ณผ ๋์์ ์คํ๋๋ฉฐ 2๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๊ณต๋ฐ๋๋ค.
const myPromise = new Promise((resolve, reject) => {
// ๋น๋๊ธฐ ์์
์ํ
const data = fetch("์๋ฒ๋ก๋ถํฐ ์์ฒญํ URL");
if (data) resolve(data); // ๋ง์ผ ์์ฒญ์ด ์ฑ๊ณตํ์ฌ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด
else reject("Error"); // ๋ง์ผ ์์ฒญ์ด ์คํจํ์ฌ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด
});
- Promise ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ค๋ฉด new ํค์๋์ Promise ์์ฑ์ ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ์ด๋ Promise ์์ฑ์ ์์ ๋๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฃ๊ฒ ๋๋๋ฐ, ์ฒซ ๋ฒ์งธ ์ธ์๋ ์์ ์ด ์ฑ๊ณตํ์ ๋ ์ฑ๊ณต(resolve)์์ ์๋ ค์ฃผ๋ ๊ฐ์ฒด์ด๊ณ , ๋ ๋ฒ์งธ ์ธ์๋ ์์ ์ด ์คํจํ์ ๋ ์คํจ(reject)์์ ์๋ ค์ฃผ๋ ์ค๋ฅ ๊ฐ์ฒด์ด๋ค.
- Promise ๊ฐ์ฒด๋ ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋ ์ดํ์ ๋ค์ ์์ ์ ์ฐ๊ฒฐ์์ผ ์งํํ ์ ์๋ค. ์์ ๊ฒฐ๊ณผ ๋ฐ๋ผ.then()ย ๊ณผ.catch()ย ๋ฉ์๋ ์ฒด์ด๋์ ํตํด ์ฑ๊ณต๊ณผ ์คํจ์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ฅผ ์งํํ ์ ์๋ค.
myPromise
.then((value) => {
// ์ฑ๊ณต์ ์ผ๋ก ์ํํ์ ๋ ์คํ๋ ์ฝ๋
console.log("Data: ", value); // ์์์ return resolve(data)์ data๊ฐ์ด ์ถ๋ ฅ๋๋ค
})
.catch((error) => {
// ์คํจํ์ ๋ ์คํ๋ ์ฝ๋
console.error(error); // ์์์ return reject("Error")์ "Error"๊ฐ ์ถ๋ ฅ๋๋ค
})
.finally(() => {
// ์ฑ๊ณตํ๋ ์คํจํ๋ ๋ฌด์กฐ๊ฑด ์คํ๋ ์ฝ๋
});
- ์ฒ๋ฆฌ๋ฅผ ์ฑ๊ณตํ๋ฉด resolve(data)ย ๋ฅผ ํธ์ถํ๊ฒ ๋๊ณ , .then()ย ์ผ๋ก ์ด์ด์ ธthenย ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์์์ ์ฑ๊ณต์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ์งํํ๋ค.
- ์ฒ๋ฆฌ๊ฐ ์คํจํ๋ฉดย ํ๋ก๋ฏธ์ค ๊ฐ์ฒด ๋ด๋ถ์์ย reject("Error")ย ๋ฅผ ํธ์ถํ๊ฒ ๋๊ณ ,ย .catch()ย ๋ก ์ด์ด์ ธ catchย ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์์์ ์ฑ๊ณต์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ์งํํ๋ค.
- ๋ค์๊ณผ ๊ฐ์ด ๋ณ๋๋ก ํจ์๋ก ๊ฐ์ธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
// ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์ ์์ฑ
function myPromise() {
return new Promise((resolve, reject) => {
if (/* ์ฑ๊ณต ์กฐ๊ฑด */) {
resolve(/* ๊ฒฐ๊ณผ ๊ฐ */);
} else {
reject(/* ์๋ฌ ๊ฐ */);
}
});
}
// ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์ ์ฌ์ฉ
myPromise()
.then((result) => {
// ์ฑ๊ณต ์ ์คํํ ์ฝ๋ฐฑ ํจ์
})
.catch((error) => {
// ์คํจ ์ ์คํํ ์ฝ๋ฐฑ ํจ์
});
- ์ ์์ ๋ ํจ์๋ฅผ ๋ง๋ค๊ณ ํด๋น ํ๋ ํจ์๋ฅผ ํธ์ถํด์ ํ๋ก๋ฏธ์ค ์์ฑ์๋ฅผ returnํ์ฌ ์์ฑ๋ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์ ๋ฐํ๊ฐ์ผ๋ก ์ป์ด ์ฌ์ฉํ๋ ๊ธฐ๋ฒ์ด๋ค.
- ์ด๋ ๊ฒ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์๋ก ๋ง๋๋ ์ด์ ๋ ๋ค์ 3๊ฐ์ง ์ ๋๊ฐ ์๋ค.
- ์ฌ์ฌ์ฉ์ฑ : ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์๋ก ๋ง๋ค๋ฉด ํ์ํ ๋๋ง๋ค ํธ์ถํ์ฌ ์ฌ์ฉํจ์ผ๋ก์จ, ๋ฐ๋ณต๋๋ ๋น๋๊ธฐ ์์ ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
- ๊ฐ๋ ์ฑ : ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์๋ก ๋ง๋ค๋ฉด ์ฝ๋์ ๊ตฌ์กฐ๊ฐ ๋ช ํํด์ ธ, ๋น๋๊ธฐ ์์ ์ ์ ์์ ์ฌ์ฉ์ ๋ถ๋ฆฌํ์ฌ ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์๋ค.
- ํ์ฅ์ฑ : ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ํจ์๋ก ๋ง๋ค๋ฉด ์ธ์๋ฅผ ์ ๋ฌํ์ฌ ๋์ ์ผ๋ก ๋น๋๊ธฐ ์์ ์ ์ํํ ์ ์๋ค. ๋ํ ์ฌ๋ฌ ๊ฐ์ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์๋ค์ ์ฐ๊ฒฐํ์ฌ ๋ณต์กํ ๋น๋๊ธฐ ๋ก์ง์ ๊ตฌํํ ์ ์๋ค.
- ์ด๋ฌํ ์ ์ผ๋ก ์ธํด ์ค๋ฌด์์๋ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ผ์ด ์๋ค๋ฉด ํจ์๋ก ๊ฐ์ธ์ ์ฌ์ฉํ๋ค. js์ fetch() ๋ฉ์๋๋ fetch() ๋ฉ์๋ ๋ด์์ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ฉด resolve()ํ์ฌ .then()์ผ๋ก ์ฒ๋ฆฌํ๋ค.
// GET ์์ฒญ ์์
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => response.json()) // ์๋ต ๊ฐ์ฒด์์ JSON ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ค.
.then((data) => console.log(data)); // JSON ๋ฐ์ดํฐ๋ฅผ ์ฝ์์ ์ถ๋ ฅํ๋ค.
Promise ๋น๋๊ธฐ ์์ ์ ์งํ ๋จ๊ณ์ ๋ฐ๋ผ 3๊ฐ์ง ์ํ๋ก ๋๋์ด ๊ด๋ฆฌํจ
- Pending(๋๊ธฐ) : ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋์ง ์์ ์ํ (์ฒ๋ฆฌ ์งํ์ค)
- Fulfilled(์ดํ) : ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋ ์ํ
- Eejected(๊ฑฐ๋ถ) : ์ฒ๋ฆฌ๊ฐ ์คํจ๋ก ๋๋ ์ํ
- ๋๊ธฐ(Pending) ์ํ๋, ๋ง ๊ทธ๋๋ก ์์ง ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ก์ง์ด ์๋ฃ ๋์ง ์์ ์ํ์ด๋ค
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("์ฒ๋ฆฌ ์๋ฃ");
}, 5000);
});
console.log(promise); // Pending (๋๊ธฐ) ์ํ
- ์ดํ(fulfilled) ์ํ๋, ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ก์ง์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ ๋ฌ๋ค๋ ๊ฒ์ ํํํ๊ธฐ ์ํ ์ํ๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
- ์์ ํ๋ก๋ฏธ์ค ์ฝ๋๋ฅผ ์คํํ๊ณ 5์ด ๋์ ๊ธฐ๋ค๋ฆฌ๋ค๊ฐ ๋ค์ ์ฝ์์ ์ถ๋ ฅํ๋ฉด. ์๋์ ๊ฐ์ด ์ดํ(fulfilled) ์ํ๋ก ๋ณํ๊ฒ ๋๋ค.
- 5์ด๊ฐ ์ง๋ resolve() ์ํ๋๋ฉด์ ํ๋ก๋ฏธ์ค ์ฑ๊ณต์ ์๋ฆฌ๋ ๊ฐ์ฒด๋ฅผ ํธ์ถํ์์ผ๋ ์ดํ ์ํ๋ก ๋ณํ ๊ฒ์ด๋ค.
- ์ดํ ์ํ๋ก ๋ณํ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ ๋ฐ๋ก ์ฒด์ด๋๋ .then() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐ์ ์ ์๋ค.
promise.then((data) => {
console.log("ํ๋ก๋ฏธ์ค๊ฐ ์ดํ ์ํ๊ฐ ๋๋ฉด์ ์ฒ๋ฆฌ์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ์ํ");
});
- reject()๋ฅผ ํธ์ถํ๋ฉด ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๊ฐ ์คํจ(rejected) ์ํ๊ฐ ๋๋ค.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject("์ฒ๋ฆฌ ์คํจ");
}, 5000);
});
- ์คํจ ์ํ๋ก ๋ณํ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ ๋ฐ๋ก ์ฒด์ด๋๋.catch()ย ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ฒ๋ฆฌ ์คํจ์ ๋ํ ํ๋์ ์ํํ๊ฒ ๋๋ค.
promise.catch((error) => {
console.log(error);
console.log("์คํจ์ ๋ํ ํ์ ์กฐ์น...");
});
์ ํ๋ธ ์์ ์์ฒญํ๋ ์ํฉ Promise ๊ฐ์ฒด์ 3๊ฐ์ง ์์)
- ์์ฒญ์๊ฐ ํน์ ์์์ ์์ฒญํ๊ธฐ ์ํด ํด๋ฆญํ๋ฉด ํด๋น ์์์ ๋ถ๋ฌ์ค๊ณ , ์์ ๋ก๋ฉ ์์
์ ๋น๋๊ธฐ์ ์ผ๋ก ๋์ํจ
- ์ฆ, ์์์ด ๋ก๋ฉ๋๊ธฐ๊น์ง ์ฌ์ฉ์๋ ๋ค๋ฅธ ์์์ ํ์ํ๊ฑฐ๋ ๋๊ธ์ ๋ค๋ ๋ฑ์ ํ๋์ ํ ์ ์๋ค.
- ์์ ๋ก๋ฉ ๊ณผ์ ์์ ์์์ด ๋ก๋ฉ ์ค์ธ ์ํ๋ฅผ โ๋๊ธฐ ์ํโ๋ผ๊ณ ํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์์ ์ผ๋ก ์์์ด ๋ก๋ฉ๋์๋ค๋ฉด ์ด๋ฅผ โํด๊ฒฐโ์ด๋ผ๊ณ ํ ์ ์์ผ๋ฉฐ, ์ด ์ํ๋ฅผ โ์ฑ๊ณต ์ํโ๋ผ๊ณ ๋งํ ์ ์๋ค. ๋ง์ฝ ์์์ด ๋ชจ์ข ์ ์ด์ ๋ก ๋ก๋ฉ๋์ง ๋ชปํ๋ค๋ฉด ์ด๋ฅผ โ๊ฑฐ๋ถโ๋ผ๊ณ ํ ์ ์์ผ๋ฉฐ, ์ด ์ํ๋ โ์คํจ ์ํโ๋ผ๊ณ ๋งํ ์ ์์
- ํ๋ก๋ฏธ์ค๊ฐ ์์ฑ๋๋ฉด, ์ฑ๊ณต/ ์คํจ ๊ฒฐ๊ณผ๋ฅผ .then / .catch / .finally ํธ๋ค๋ฌ๋ฅผ ํตํด ๋ฐ์ ๋ค์ ํ์ ์์
์ ์ํํ ์ ์๋ค. ํ๋ก๋ฏธ์ค ํธ๋ค๋ฌ๋ ํ๋ก๋ฏธ์ค์ ์ํ์ ๋ฐ๋ผ ์คํ๋๋ ์ฝ๋ฐฑ ํจ์๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
- .then() : ํ๋ก๋ฏธ์ค๊ฐ ์ดํ(fulfilled)๋์์ ๋ ์คํํ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฑ๋กํ๊ณ , ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํ
- .catch() : ํ๋ก๋ฏธ์ค๊ฐ ๊ฑฐ๋ถ(rejected)๋์์ ๋ ์คํํ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฑ๋กํ๊ณ , ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํ
- .finally() : ํ๋ก๋ฏธ์ค๊ฐ ์ดํ๋๊ฑฐ๋ ๊ฑฐ๋ถ๋ ๋ ์๊ด์์ด ์คํํ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฑ๋กํ๊ณ , ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํ
- ๋ง์น try - catch - finally ๊ตฌ์กฐ์ ์ ์ฌํ๋ค.
- ํ๋ก๋ฏธ์ค ์ฒด์ด๋์ด๋ ํ๋ก๋ฏธ์ค ํธ๋ค๋ฌ๋ฅผ ์ฐ๋ฌ์ ์ฐ๊ฒฐํ๋ ๊ฒ์ ๋งํ๋ค. ์ด๋ ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์์ ์ ์์ฐจ์ ์ผ๋ก ์ํํ ์ ์๋ค๋ ํน์ง์ด ์๋ค.
- ํ๋ก๋ฏธ์ค๋ then, catch, finally ํ์ ์ฒ๋ฆฌ ๋ฉ์๋๋ฅผ ํตํด ์ฝ๋ฐฑ ํฌ์ ํด๊ฒฐํ๋ค.
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 ์ถ๋ ฅ
})
- ์ doSomething ํจ์๋ฅผ ํธ์ถํ์ฌ ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑํ๊ณ , then ๋ฉ์๋๋ฅผ ํตํด ์ดํ ํธ๋ค๋ฌ๋ฅผ ์ฐ๊ฒฐํ๋ ๊ณผ์ ์ด๋ค. ๊ฐ ์ดํ ํธ๋ค๋ฌ๋ ์ด์ ํ๋ก๋ฏธ์ค์ ๊ฐ์ 50์ ๋ํ ๊ฐ์ ๋ฐํํ๊ณ , ๋ง์ง๋ง ์ดํ ํธ๋ค๋ฌ๋ ์ต์ข ๊ฐ์ ์ฝ์์ ์ถ๋ ฅํ๋ค.
- ์ด๋ฌํ ์ฒด์ด๋์ด ๊ฐ๋ฅํ ์ด์ ๋ then ํธ๋ค๋ฌ์์ ๊ฐ์ ๋ฆฌํดํ๋ฉด, ๊ทธ ๋ฐํ๊ฐ์ ์๋์ผ๋ก ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ก ๊ฐ์ธ์ ธ ๋ฐํ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค์ then ํธ๋ค๋ฌ์์ ๋ฐํ๋ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐ์ ์ฒ๋ฆฌํ๋ค. ์ด์ ํ๋ก๋ฏธ์ค ์ํ์ ํ๋ฆ๋๋ฅผ ํํํ๋ฉด ์๋์ ๊ฐ๋ค.
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 ํธ๋ค๋ฌ์ ์ ํํ๋๋ก ์ค์ ํ ์ ์๋ค.
new Promise((resolve, reject) => {
throw new Error("์๋ฌ ๋ฐ์!");
})
.catch(function(error) {
console.log("์๋ฌ๊ฐ ์ ์ฒ๋ฆฌ๋์์ต๋๋ค. ์ ์์ ์ผ๋ก ์คํ์ด ์ด์ด์ง๋๋ค.");
})
.then(() => {
console.log("๋ค์ ํธ๋ค๋ฌ๊ฐ ์คํ๋ฉ๋๋ค.")
})
.then(() => {
console.log("๋ค์ ํธ๋ค๋ฌ๊ฐ ๋ ์คํ๋ฉ๋๋ค.")
});
- catch ํธ๋ค๋ฌ ๋ค์์ผ๋ก then ํธ๋ค๋ฌ๊ฐ ์ด์ด์ ์ฒด์ด๋ ๋์ด ์๋ค๋ฉด, ์๋ฌ๊ฐ ์ฒ๋ฆฌ๋๊ณ ๊ฐ๊น์ด then ํธ๋ค๋ฌ๋ก ์ ์ด ํ๋ฆ์ด ๋์ด๊ฐ ์คํ์ด ์ด์ด์ง๊ฒ ๋๋ค.
- ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ ์์ฑ์ ํจ์ ์ธ์๋ ์ฌ๋ฌ ๊ฐ์ง ์ ์ ๋ฉ์๋(static method)๋ฅผ ์ ๊ณตํ๋ค. ์ ์ ๋ฉ์๋๋ ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํ & ์์ฑํ์ง ์๊ณ ๋ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ณด๋ค ํจ์จ์ ์ด๊ณ ๊ฐํธํ๊ฒ ๊ตฌํํ ์ ์๋๋ก ๋์์ค๋ค.
// ํ๋ก๋ฏธ์ค ์์ฑ์๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํจ์
function getPromiseNumber() {
return new Promise((resolve, reject) => {
const num = Math.floor(Math.random() * 10); // 0 ~ 9 ์ฌ์ด์ ์ ์
resolve(num); // ํ๋ก๋ฏธ์ค ์ดํ
});
}
// Promise {<fulfilled>: 3}
- 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 ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค
// ์ฃผ์ด์ง ์ฌ์ ๋ก ๊ฑฐ๋ถ๋๋ ํ๋ก๋ฏธ์ค ์์ฑ
const p = Promise.reject(new Error("error"));
// ๊ฑฐ๋ถ ์ฌ์ ๋ฅผ ์ถ๋ ฅ
p.catch((error) => console.error(error)); // Error: error
- ๋ฐฐ์ด, 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.all() ๋ฉ์๋์ ์์ ๋ฒ์ ์ผ๋ก, ์ฃผ์ด์ง ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ ์ฒ๋ฆฌ๋๋ฉด ๋ชจ๋ ํ๋ก๋ฏธ์ค ๊ฐ๊ฐ์ ์ํ์ ๊ฐ (๋๋ ๊ฑฐ๋ถ ์ฌ์ )์ ๋ชจ์๋์ ๋ฐฐ์ด์ ๋ฐํํ๋ค.
// 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.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);
});
// ๊ฒฐ๊ด๊ฐ :
// promise2 succeeded
- ์ ์ฝ๋๋ Promise.any() ๋ฉ์๋์ ๊ฒฐ๊ณผ๋ก promise2์ ์ฒ๋ฆฌ๊ฐ ๊ฐ์ฅ ๋จผ์ ๋์ถ๋จ์ ๋ณผ ์ ์๋ค. ์ฒซ๋ฒ์งธ๋ก ์ดํ(fulfilled) ๋ ํ๋ก๋ฏธ์ค๋ง์ ์ทจ๊ธํ๊ธฐ ๋๋ฌธ์ ๋๋จธ์ง promise1๊ณผ promise3์ ๊ฑฐ๋ถ(rejected)๋ ๋ฌด์๋๊ฒ ๋๋ค.
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"]
});
- ๋ง์ฝ ์์ฒญ๋ ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ ๊ฑฐ๋ถ(rejected)๋๋ฉด, AggregateError ๊ฐ์ฒด๋ฅผ ์ฌ์ ๋ก ํ๋ ๊ฑฐ๋ถ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
new Promise((resolve, reject) => {
throw new Error("์๋ฌ ๋ฐ์!");
})
.catch(function (error) {
console.log("์๋ฌ๊ฐ ์ ์ฒ๋ฆฌ๋์์ต๋๋ค. ์ ์์ ์ผ๋ก ์คํ์ด ์ด์ด์ง๋๋ค.");
})
.then(() => {
console.log("๋ค์ ํธ๋ค๋ฌ๊ฐ ์คํ๋ฉ๋๋ค.");
})
.then(() => {
console.log("๋ค์ ํธ๋ค๋ฌ๊ฐ ๋ ์คํ๋ฉ๋๋ค.");
});
- Promise.race()๋ Promise.any() ์ ๊ฐ์ด ์ฌ๋ฌ ๊ฐ์ ํ๋ก๋ฏธ์ค ์ค ๊ฐ์ฅ ๋จผ์ ์ฒ๋ฆฌ๋ ํ๋ก๋ฏธ์ค์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ๋ค. ํ์ง๋ง ์ฐจ์ด์ ์ด ์กด์ฌํ๋ค.
- Promise.any()๋ ๊ฐ์ฅ ๋จผ์ fulfilled(์ดํ) ์ํ๊ฐ ๋ ํ๋ก๋ฏธ์ค๋ง์ ๋ฐํํ๊ฑฐ๋, ํน์ ์ ๋ถ rejected(์คํจ) ์ํ๊ฐ ๋ ํ๋ก๋ฏธ์ค(AggregateError)๋ฅผ ๋ฐํํ๋ค.
- ๋ฐ๋ฉด Promise.race()๋ fulfilled(์ดํ), rejected(์คํจ) ์ฌ๋ถ ์๊ด์์ด ๋ฌด์กฐ๊ฑด ์ฒ๋ฆฌ๊ฐ ๋๋ ํ๋ก๋ฏธ์ค ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ๋ค.
Promise.any ์์)
Promise.race ์์)
- Callback Queue์ ์ข
๋ฅ์๋ (Macro)Task Queue, MicroTask Queue 2๊ฐ์ง๊ฐ ์๋ค
- ๊ทธ์ค ์๋ฐ์คํฌ๋ฆฝํธ Promise ๊ฐ์ฒด์ ์ฝ๋ฐฑ์ด ์์ด๋ ๊ณณ์ด ๋ฐ๋ก MicroTask Queue์ด๋ค. ๊ทธ๋ฆฌ๊ณ MicroTask Queue๋ ๊ทธ ์ด๋ค ๊ณณ๋ณด๋ค ๊ฐ์ฅ ๋จผ์ ์ฐ์ ์ผ๋ก ์ฝ๋ฐฑ์ด ์ฒ๋ฆฌ๋๊ฒ ๋๋ค.
console.log('Start!');
setTimeout(() => {
console.log('Timeout!');
}, 0);
Promise.resolve('Promise!').then(res => console.log(res));
console.log('End!');
- Call Stack์console.log('Start!') ์ฝ๋ ๋ถ๋ถ์ด ์์ธ ๋ค ์คํ ๋์ด ์ฝ์์ฐฝ์ "Start!"ย ๊ฐ ์ถ๋ ฅ
- setTimeout ์ฝ๋๊ฐ ์ฝ ์คํ์ ์ ์ฌ๋๊ณ ์คํ๋๋ฉด, ๊ทธ ์์ ์ฝ๋ฐฑ ํจ์๊ฐ ์ด๋ฒคํธ ๋ฃจํ์ ์ํด Web API๋ก ์ฎ๊ฒจ์ง๊ณ ํ์ด๋จธ๊ฐ ์๋ํ๊ฒ ๋๋ค. (0์ด๋ผ์ ์ฌ์ค์ ๋ฐ๋ก ํ์ด๋จธ๋ ์ข ๋ฃ๋๋ค)
- ํ์ด๋จธ๊ฐ ์ข ๋ฃ๋จ์ ๋ฐ๋ผsetTimeoutย ์ ์ฝ๋ฐฑ ํจ์๋ย MacroTask Queue์ ์ด๋ฒคํธ ๋ฃจํ์ ์ํด ์ ์ฌ๋๊ฒ ๋๋ค.
- Promise ์ฝ๋๊ฐ ์ฝ์คํ์ ์ ์ฌ ๋์ด ์คํ๋๊ณ then ํธ๋ค๋ฌ์ ์ฝ๋ฐฑ ํจ์๊ฐ ์ด๋ฒคํธ ๋ฃจํ์ ์ํด MicroTaskย Queue์ ์ ์ฌ๋๊ฒ ๋๋ค.
- console.log('End!') ์ฝ๋๊ฐ ์คํ๋๊ณ "End!" ํ ์คํธ๊ฐ ์ฝ์์ฐฝ์ ์ถ๋ ฅ๋๋ค.
- ๋ชจ๋ ๋ฉ์ธ ์ค๋ ๋์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๊ฐ ์คํ์ด๋์ด ๋์ด์ Call Stack์ ์คํํ ์คํ์ด ์์ด ๋น์์ง๊ฒ ๋๋ค.
- ๊ทธ๋ฌ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ด๋ฅผ ๊ฐ์งํ์ฌ, Callback Queue์ ๋จ์์๋ ์ฝ๋ฐฑ ํจ์๋ค์ ๋นผ์ Call Stack์ ์ ์ฌํ๊ฒ ๋๋ค
- ์ด๋ 2์ข ๋ฅ์ Queue ์ค MicroTask Queue์ ๋จ์์๋ ์ฝ๋ฐฑ์ด ์ฐ์ ์ ์ผ๋ก ์ฒ๋ฆฌ๋๋ค. (๋ง์ผ ์ฝ๊ฐ์ด ์ฌ๋ฌ๊ฐ๊ฐ ์๋ค๋ฉด ์ ๋ถ ์ฒ๋ฆฌ๋๋ค)
- MicroTask Queue๊ฐ ๋น์ด์ง๋ฉด, ์ด์ ์ด๋ฒคํธ ๋ฃจํ๋ MacroTask Queue์ ์๋ ์ฝ๋ฐฑ ํจ์๋ฅผ Call Stack์ ์ ์ฌํด ์คํ๋๊ฒ ๋๋ค.
-
Promise.resolve() : ๋น๋๊ธฐ ์์ ์ ์ํ๋ฅผ ์ฑ๊ณต์ผ๋ก ๋ฐ๊พธ๋ ํจ์
-
Promise.reject() : ๋น๋๊ธฐ ์์ ์ ์ํ๋ฅผ ์คํจ๋ก ๋ฐ๊พธ๋ ํจ์
๐ข ์์ ์ดํด ๋ณด์๋ฏ์ด ํ๋ก๋ฏธ์ค๋ ๋น๋๊ธฐ ์์ ์ ์ํ๋ฅผ ๋๊ธฐ(Pending), ์ฑ๊ณต(Fulfilled), ์คํจ(Rejected)๋ก ๋๋์ด ๊ด๋ฆฌํจ. ์คํ ํจ์๊ฐ ์ ๊ณต๋ฐ๋ 2๊ฐ์ ๋งค๊ฐ๋ณ์๋ ๋๊ธฐ ์ํ์ ๋น๋๊ธฐ ์์ ์ ์ฑ๊ณต ๋๋ ์คํจ ์ํ๋ก ๋ณ๊ฒฝํ๋ ์ญํ ์ ํจ
์คํ ํจ์์์ ๋งค๊ฐ๋ณ์๋ก ์ ๊ณต๋ resolve๋ฅผ ํธ์ถํ์ฌ ์์ ์ํ๋ฅผ ์ฑ๊ณต ์ํ๋ก ๋ณ๊ฒฝํ๋ ์์)
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("์ฑ๊ณต");
}, 500);
});
- ์ ์์ ๋ 0.5์ด ๊ธฐ๋ค๋ฆฐ ํ resolve๋ฅผ ํธ์ถํ์ฌ ์ธ์๋ก ์ ๋ฌํ ๊ฐ โ์ฑ๊ณตโ์ ๋น๋๊ธฐ ์์ ์ ๊ฒฐ๊ด๊ฐ์ด ๋๋ค.
- ์ด ๊ฒฐ๊ด๊ฐ์ ๋น๋๊ธฐ ์์ ์ด ์๋ ๊ณณ์์ ์ด์ฉํ๋ ค๋ฉด ํ๋ก๋ฏธ์ค ๊ฐ์ฒด์ then ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ฉด ๋๋ค. then ๋ฉ์๋๋ ์ธ์๋ก ์ ๋ฌํ ์ฝ๋ฐฑ ํจ์์ ๋น๋๊ธฐ ์์ ์ด ์ฑ๊ณตํ์ ๋ ์คํํ๋ค.
๋ชจ๋ js ๋ฅ๋ค์ด๋ธ https://inpa.tistory.com/entry/๐-์๋ฐ์คํฌ๋ฆฝํธ-์ด๋ฒคํธ-๋ฃจํ-๊ตฌ์กฐ-๋์-์๋ฆฌ#promise๋ด๋ถ๋์_๊ณผ์
ํ์ ํฌ๊ธฐ ๋ฆฌ์กํธ