Javascript - Promise
Promise
promise๋ ๋น๋๊ธฐ ๋ฉ์๋์์ ๋ง์น ๋๊ธฐ ๋ฉ์๋์ฒ๋ผ ๊ฐ์ ๋ฐํํ ์ ์์ต๋๋ค. ๋ค๋ง ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ์ง๋ ์๊ณ , ๋์ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํด์ ๋ฏธ๋์ ์ด๋ค ์์ ์ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ๋ค.
**์ํ **
- pending(๋๊ธฐ) : ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ก์ง์ด ์์ง ์๋ฃ๋์ง ์์ ์ํ
- fulfilled(์ดํ) : ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋์ด ํ๋ก๋ฏธ์ค๊ฐ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐํํด์ค ์ํ
- rejected(๊ฑฐ๋ถ) : ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ํ
1. Producer (Promise ๋ง๋ค๊ธฐ)
- ์๋ก์ด Promise๊ฐ ๋ง๋ค์ด์ง ๋๋ ์ ๋ฌํ executorํจ์๊ฐ ๋ฐ๋ก ์คํ์ด ๋๋ค.
const promise = new Promise((resolve, reject) => {
// doing some heavy work(networt, read files)
console.log("doing something...");
setTimeout(() => {
resolve("hello!");
}, 2000);
});
โdoing somethingโฆโ์ดํ 2์ด ๋ค์ hello!๊ฐ ์ฝ์์ ์ฐํ ๊ฒ์ ๋ณผ ์ ์๋ค.
2. Consumers : then, catch, finally (Promise ์ฌ์ฉํ๊ธฐ)
- then : promise ๊ฐ ์ข ๋ฃ๊ฐ ๋๋ฉด resolve ์ ๋ค์ด๊ฐ ๊ฐ์ ๋ฐ์ ์ ์๋ค.
- catch : reject ๋ ๊ฒฝ์ฐ์๋ then ์ผ๋ก ๋ฐ์ ๊ฒฝ์ฐ, ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉฐ ์ด ์๋ฌ๋ฅผ catch๋ก ์ก์ ์ ์๋ค.
- finally : ์ฑ๊ณต๊ณผ ์คํจ์ ๊ด๊ณ์์ด ๋ฌด์กฐ๊ฑด ๋ง์ง๋ง์ ํธ์ถ๋์ด์ง๋ค.
const promise = new Promise((resolve, reject) => {
// doing some heavy work(networt, read files)
console.log("doing something...");
setTimeout(() => {
reject(new Error("no network"));
}, 2000);
});
promise //
.then((value) => {
console.log(value);
})
.catch((error) => {
console.log(error);
})
.finally(() => {
console.log("finally");
});
3. Promise chaining (Promise ์ฐ๊ฒฐํ๊ธฐ)
const fetchNuber = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000);
});
//1์ด ์๋ค๊ฐ 1๋ฅผ ์ ๋ฌ
fetchNuber //
.then((num) => num * 2) // 1*2 = 2
.then((num) => num * 3) // 2*3 = 6
.then((num) => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num - 1), 1000); //6-1 = 5
});
})
.then((num) => console.log(num));
then์ ๊ฐ์ ๋ฐ๋ก ์ ๋ฌํ ์๋ ์๊ณ Promise๋ฅผ ์ ๋ฌํ ์๋ ์๋ค. 2์ด์ ์๊ฐ ์์ ๋ค 5๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
4. ์ค๋ฅ์ฒ๋ฆฌ
const getHen = () =>
new Promise((resolve, reject) => {
setTimeout(() => resolve("๐"), 1000);
});
const getEgg = (hen) =>
new Promise((resolve, reject) => {
setTimeout(() => reject(new Error(`${hen} => ๐ฅ`)), 1000);
});
const cook = (egg) =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(`${egg} => ๐ณ`), 1000);
});
์ด 3๊ฐ์ง์ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฆฌํดํ๋ ํจ์๋ก, 1์ด ์๋ค๊ฐ ๐์ ๋ฆฌํด, ๐์ ๋ฐ์์์ ๐ฅ๋ฅผ ๋ฆฌํด, ๐ฅ๋ฅผ ๋ฐ์์์ ๐ณ๋ฅผ ๊ฐ์ ํ์๋ค.
getHen()
.then((hen) => getEgg(hen))
.then((egg) => cook(egg))
.then((cook) => console.log(cook));
// โฌ๏ธ ํ๊ฐ์ง๋ง ๋ฐ์์ ๊ทธ๋๋ก ์ ๋ฌํ๋ ๊ฒฝ์ฐ์๋ ์๋์ฒ๋ผ ์๋ต์ด ๊ฐ๋ฅํ์ฌ ์งง๊ฒ ํํํ ์ ์๋ค.
getHen() //
.then(getEgg)
.then(cook)
.then(console.log);
์๋ฌ๋ฅผ ์ก์ง ์์๊ธฐ ๋๋ฌธ์ ์๋ฌ๋ฉ์ธ์ง๊ฐ ๋จ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ๋ ๋ค ๋งจ ๋ค์ catch๋ฅผ ํตํด ์๋ฌ๋ฅผ ์ก์์ฃผ๊ฒ ๋๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ์ง๋ง ์๋ฌ๊ฐ ๋งจ ์๋๋ก ์ ๋ฌ๋๋ฉด์ catch๊ฐ ์กํ ๊ฒ์ ๋ณผ ์ ์๋ค.
getHen() //
.then(getEgg)
.then(cook)
.then(console.log)
.catch(console.log);
getHen() //
.then(getEgg)
.catch((error) => {
return "๐ฅ";
})
.then(cook)
.then(console.log)
.catch(console.log);
๊ณ๋์ ๋ฐ์์ฌ ๋ ๋ฌธ์ ๊ฐ ์๊ธด๋ค๋ฉด, ๋ค๋ฅธ ๊ฑธ๋ก ๋์ฒดํด์ Promise ์ฒด์ธ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค.
โจ ์ฝ๋ฐฑ์ง์ฅ -> Promise ์ด์ฉํ๊ธฐ
์ง๋ ์๊ฐ์ ์์ฑํ ์ฝ๋ฐฑ์ง์ฅ์ Promise๋ฅผ ์ด์ฉํ์ฌ ๊น๋ํ๊ฒ ์ฝ๋์ฒ๋ฆฌ ํ ์ ์๋ค.
class UserStorage {
loginUser(id, password) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (
(id === "hyesung" && password === "qwerty") ||
(id === "coder" && password === "zxcvb")
) {
resolve(id);
} else {
reject(new Error("not found"));
}
}, 2000);
});
}
getRoles(user) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (user === "hyesung") {
resolve({ name: "hyesung", role: "admin" });
} else {
reject(new Error("no access"));
}
}, 1000);
});
}
}
const userStorage = new UserStorage();
const id = prompt("enter your id");
const password = prompt("enter your password");
userStorage
.loginUser(id, password)
.then((user) => userStorage.getRoles(user))
.then((user) => alert(`Hello ${user.name}, you have a ${user.role} role`))
.catch(console.log);
์ถ์ฒ : ๋๋ฆผ์ฝ๋ฉ by ์๋ฆฌ https://youtu.be/JB_yU6Oe2eE