๐ก ๋น๋๊ธฐ์ ํ๋ก๋ฏธ์ค
"๋๊ธฐ๋ค, ๋น๋๊ธฐ๋ค", ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋ง์ด ๋ค์ด์จ ๋ง์ด๋ค. ๋น๋๊ธฐ์ ํ๋ก๋ฏธ์ค๋ฅผ ์ดํดํ๋ค๋ ๊ฒ์ ํ๋ก๊ทธ๋จ์ ํ๋ฆ์ ์ดํดํ๊ณ ์ฑ๋ฅ ์ต์ ํ, ์๋ฌ ํธ๋ค๋ง ๋ฑ์ ์ฒ๋ฆฌํ ์ ์๋ ์์ฃผ ์ค์ํ ์์์ด๊ธฐ ๋๋ฌธ์ ์ ๋ฆฌํด ๋ณด๊ณ ์ ํ๋ค.
๋จผ์ ๋๊ธฐ์ ๋น๋๊ธฐ๋ ๋ญ๊น?
๐๋๊ธฐ์ ๋น๋๊ธฐ
์ ๊ทธ๋ฆผ์ ๋๊ธฐ์ ์ธ ๊ณผ์ ์ ํ๋์ ์ผ์ด ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ๋ค์ ์ผ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ ์๋ฏธํ๊ณ , ์๋ ๊ทธ๋ฆผ์ ๋น๋๊ธฐ ๊ณผ์ ์ผ๋ก ํ๋์ ์ผ์ ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด ์๋๋ผ ์ผ์ ๋์์ ์ฒ๋ฆฌํ๊ณ ์๋ค. ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ณผ์ ์ ์ฌ๋ฌ ์ผ์ ๊ฐ์ด ํ๊ณ ์๊ธฐ ๋๋ฌธ์ ํจ์ฌ ์๊ฐ์ด ์ ๊ฒ ๊ฑธ๋ฆฌ๋ ๊ฒ์ ์ ์ ์๋ค.
์ด๋ ๊ฒ ํ๋์ ์ผ์ ์ฒ๋ฆฌํ๋๋ฐ ์ค๋ ์๊ฐ์ด ๊ฑธ๋ ค ์ดํ ์์ ์ ๋ง๊ฒ ๋๋ ๊ฒฝ์ฐ, ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํตํด ํจ์จ์ ๋์ผ ์ ์๋ค.
a,b,c ๋ผ๋ ๋ณ์๋ฅผ ๊ฐ๋จํ๊ฒ ํธ์ถํ๊ณ ์๋ ์์๋ฅผ ๋ณด์.
const a = 1
const b = 2
const c = 3
console.log(a)
console.log(b)
console.log(c)
//๊ฒฐ๊ณผ: 1,2,3
//๋น๋๊ธฐ
console.log(a)
setTimeout(() => {
console.log(b)
}, 0)
console.log(c)
//๊ฒฐ๊ณผ: 1,3,2๋๊ธฐ ์ฝ๋์ธ ์์ ์์๋ ๊ฒฐ๊ณผ๊ฐ ์ผ์ ์์๋๋ก 1,2,3์ด๋ ๊ฒฐ๊ณผ๋ฅผ ๋ํ๋ด๊ณ , ๋น๋๊ธฐ ์ฝ๋์ธ ์๋์ ์์๋ 1,3,2๋ผ๋ ์ฝ๋๋ฅผ ์ ์ ์์์ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ๊ฒ ๋์๋ค.
console.log(b)๋ฅผ console.log(c)๋ณด๋ค ๋จผ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ์ฝ์์ง๋ง, ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ์ํด ์์๋๋ก ์งํํ๋ ๊ฒ์ด ์๋๋ผ b๋ฅผ ๋ค๋ฅธ ๊ณณ์์ ์ฒ๋ฆฌํ ํ์ ๊ฐ์ ธ์ค๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค. ๋ง์ฝ b๊ฐ ์ฒ๋ฆฌํ๋๋ฐ ์์ฒญ ์ค๋ ๊ฑธ๋ฆฌ๋ ๊ณผ์ ์ด๋ผ๊ณ ๊ฐ์ ํ๋ค๋ฉด, ๋๊ธฐ์ ์ฝ๋์์๋ ์ค๋ ์๊ฐ ๋ค์ c๊ฐ ํธ์ถ์ด ๊ฐ๋ฅํ๋ค. ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ก ์ธํด ์ค๋ ๊ฑธ๋ฆฌ๋ b๋ผ๋ ์ผ์ ๋๊ฒจ์ ์ฒ๋ฆฌํ๋ ๋์ c๋ฅผ ์ฒ๋ฆฌํ๋ฉด ํจ์ฌ ํจ์จ์ ์ผ๋ก ์ผ์ ์ฒ๋ฆฌํ ์ ์๋ค.
๊ทธ๋ฌ๋ฉด ์ด๋ ๊ฒ ๋ณด๋ด์ง ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ ์ด๋์, ์ด๋ป๊ฒ ์ด๋ฃจ์ด์ง๋ ๊ฑธ๊น?
โฐ ๋ชจ๋ ์ผ์ ์์๋ฅผ ๊ด๋ฆฌํ๋ ์ค์ผ์ค๋ฌ, Event loop
์๋ฐ์คํฌ๋ฆฝํธ๋ ์ฑ๊ธ ์ค๋ ๋๋ก ์ผ์ด ์ฒ๋ฆฌ๋๋ค. ์ฌ๋ฌ ๊ฐ์ ์ผ์ ํ๋ฒ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์๋๋ผ, ํ๋ฒ์ ํ๋์ ์ผ๋ง ์ฒ๋ฆฌํ ์ ์๋ค๋ ์๋ฏธ๋ค. ๊ทธ๋ฌ๋ฉด ์์ ๋ณด์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ ์ด๋์ ์ด๋ฃจ์ด์ง๋ ์๋ฌธ์ด ๋ ๋ค. ๋น๋๊ธฐ๋ ์ฌ๋ฌ ๊ฐ์ ์ผ์ ๋์์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด๊ณ , ์ฐ๋ฆฌ๊ฐ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ด์ฉํ ๋ ์ฌ๋ฌ ๊ฐ์ ์ผ์ ๋์์ ํ๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋๋ฐ ์ด๋ป๊ฒ ๋ ๊ฑธ๊น?
์ด๊ฒ์ ์ดํดํ๊ธฐ ์ํด์๋ ๋จผ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง๊ณผ ๋ธ๋ผ์ฐ์ ์ ์ญํ ์ ์ดํดํ ํ์๊ฐ ์๋ค.
๋จผ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์๋ ํ๊ณผ ์ฝ์คํ์ผ๋ก ๊ตฌ์ฑ๋์ด ์๋ค. ์ฝ์คํ์ ์คํ ์ปจํ ์คํธ ์คํ๊ณผ ๊ฐ์ ๊ฒ์ผ๋ก, ์คํ ์ปจํ ์คํธ์ ์์๋ฅผ ๊ธฐ์ตํ๊ณ ์๋ค. ํ์๋ ๊ฐ์ฒด๊ฐ ์ ์ฅ๋๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ผ๋ก ๋์ ์ผ๋ก ์๊ธฐ๋ ๋ณ์๋ค, ํฌ๊ธฐ๋ฅผ ์ ํ ์ ์๋ ๊ฐ์ฒด๋ค์ ์ ์ฅํ๊ณ ์คํ ์ปจํ ์คํธ๋ ํ์ ์ ์ฅ๋ ๊ฐ์ฒด๋ค์ ์ฐธ์กฐํ๊ณ ์๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์์ ๋งํ ๋๋ก ์๋ฐ์คํฌ๋ฆฝํธ ์์ฒด๋ ์ฑ๊ธ ์ค๋ ๋๋ก ์ฝ์คํ์ ์์ฌ์๋ ์์๋ก ์ฝ๋๋ฅผ ํ๊ฐํ๊ณ ์คํํ๋ ๊ธฐ๋ฅ๋ง ๊ฐ๊ณ ์๋ค.
๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํด์๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ์๋ํ๋ Node Js๋ ๋ธ๋ผ์ฐ์ ๊ฐ ๋์์ค์ผ ํ๋ค. ์์ ์ฝ๋์์ ์ฌ์ฉ๋ setTimeout๊ณผ ๊ฐ์ ๋ธ๋ผ์ฐ์ /Node API๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ํ๊ฐํ๊ณ ์คํํ๋๋ฐ, ํธ์ถ๋๋ ์์ ๊ณผ ์ฝ๋ฐฑํจ์์ ๋ฑ๋ก์ ๋ธ๋ผ์ฐ์ ์ Node.js๊ฐ ํด ์ค๋ค. ์ด๋ ๊ฒ ๋ฑ๋กํ ์ฝ๋ฐฑํจ์๋ฅผ ๋ณด๊ดํ๋ ๊ณณ์ Task Queue๋ค. Task Queue์ ์ ์ฅ๋ callbackํจ์๋ ํ๋์ฉ event loop์ด callstack์ด ๋น์ด ์์ ๋ ๊ฐ์ ธ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ์ฒ๋ฆฌํ ์ ์๊ฒ ํ๋ค.
์ด๋ ๊ฒ ๋ค๋ฅธ ์ญํ ์ ๊ฐ๊ณ ์๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง๊ณผ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฐ๊ฒฐํด ์๋ฐ์คํฌ๋ฆฝํธ์ ๋์์ฑ์ ์ง์ํ๋ ๊ฒ์ด Event loop์ด๋ค.

์์ ๋น๋๊ธฐ ์์ ๋ฅผ ๋ค์ ์ค๋ช ํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
const a = 1
const b = 2
const c = 3
console.log(a)
setTimeout(() => {
console.log(b)
}, 0)
console.log(c)
//๊ฒฐ๊ณผ: 1,3,2- ์ ์ญ์ปจํ ์คํธ๊ฐ ๋ง๋ค์ด์ง๊ณ ์ฝ์คํ์ ๋ค์ด๊ฐ๋ค.
- ํ๊ฐ ๊ณผ์ ์ ํตํด ๋ณ์ a,b,c๊ฐ ๋ฑ๋ก๋๊ณ ์คํ ๊ณผ์ ์์ WebAPI์ธ SetTimeOut์ ํจ์ ์ปจํ ์คํธ๋ฅผ ๋ง๋ค์ด ์ฝ์คํ์ ์ถ๊ฐ๋๋ค.
- SetTimeOut ๋ด๋ถ ์ฝ๋ฐฑ ํจ์๋ ๋ธ๋ผ์ฐ์ ๋ก ๋์ด๊ฐ๊ณ ํจ์ ์ปจํ ์คํธ๋ ์ข ๋ฃ๋์ด ์ฝ์คํ์์ ์ ๊ฑฐ๋๋ค.
- ํ์ด๋จธ๊ฐ ์๋ฃ๋๋ฉด taskQueue์ ์ฝ๋ฐฑ ํจ์๊ฐ ๋ฑ๋ก๋๋๋ฐ, ์ด ๊ณผ์ ์์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ๋ค์ ์คํ ์ฝ๋์ธ console.log(c)๊ฐ ์ฒ๋ฆฌํ๋ค.
- call stack์ด ๋ค ๋น๋ฉด taskQueue์ ์๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ๊ฐ์ ธ์ console.log(c)๋ฅผ ์ํํ๋ค.
์ด๋ฌํ ๊ณผ์ ๋๋ฌธ์ ๊ฒฐ๊ณผ๊ฐ 1,3,2๋ก ์ฒ๋ฆฌ๋์๋ ๊ฒ์ด๋ค.
์ฃผ์ํ ์ ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ์ฑ๊ธ ์ค๋ ๋์ด์ง๋ง ๋ธ๋ผ์ฐ์ ๋ ๋ฉํฐ์ค๋ ๋๋ก ์ฌ๋ฌ๊ฐ์ง ์ผ์ ๋์์ ์ฒ๋ฆฌํด ์ค ์ ์๋ค.
๊ทธ๋ฌ๋ฉด ๋ชจ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ฝ๋ฐฑํจ์๋ก ํ๋ฉด ๋๋๊ฑธ๊น?
โ ์ฝ๋ฐฑ ํจ์์ ํ๊ณ
์ฝ๋ฐฑํจ์๋ ์ฝ๋ฐฑํจ์ ๋ด๋ถ ๊ฒฐ๊ณผ๋ฅผ ์ธ๋ถ๋ก ๋ฐํํ ์ ์๋ค. ์์ ์ฌ์ฉํ setTimeOut์ ์๋ก ์ค๋ช ํด๋ณด๋ฉด ์ฝ๋ฐฑ ํจ์๊ฐ ์คํ๋๋ ์์ ์๋ setTimeOut์ ํจ์ ์ปจํ ์คํธ๊ฐ ์กด์ฌํ์ง ์๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์์ ์ค์ฝํ์ ๋ณ์์ ๊ฐ์ ํ ๋นํ๊ฑฐ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ try-catch๋ฌธ์ผ๋ก ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ํ๋ คํด๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ์์ ์์์ ์๋ฌ๋ ์กํ์ง ์๋๋ค.
์คํ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋ค์ ๊ณผ์ ์ ์ ๋ฌํ๊ธฐ ์ํด์๋ ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์์ ์ฒ๋ฆฌ๋์ด์ผ ํ๊ณ , ์ด ๊ณผ์ ์ด ์ค์ฒฉ๋๊ฒ ๋๋ฉด์ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๋ "Callback hell"์ด ๋๋ค.
์๋ ์ฝ๋๋ Callback hell์ ์์ ๋ก ๋ก๊ทธ์ธ ๊ณผ์ ์ ๊ตฌํํ ์ฝ๋๋ค. ์ด๋ ๊ฒ ์ฝ๋๊ฐ ์ง์ฌ์ ธ ์๋ค๋ฉด ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๊ณ , ์ ์ง ๋ณด์์๋ ์ด๋ ค์ด ๋จ์ ์ ๊ฐ๋๋ค.
class UserStorage {
loginUser(id, password, onSuccess, onError) {
setTimeout(() => {
if (
(id === "seul" && password === "123") ||
(id === "kim" && password === "456")
) {
onSuccess(id)
} else {
onError(new Error("error"))
}
}, 2000)
}
getRoles(user, onSuccess, onError) {
setTimeout(() => {
if (user === "seul") {
onSuccess({ name: "seul", role: "admin" })
} else {
onError(new Error("error"))
}
}, 1000)
}
}
const userStorage = new UserStorage()
const id = prompt("์์ด๋๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์!")
const password = prompt("๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์!!")
userStorage.loginUser(
id,
password,
user => {
userStorage.getRoles(
user,
userWithRole => {
alert(
`hello ${userWithRole.name}, you have a ${userWithRole.role} role`
)
},
error => {
console.log("์๋ฌ2")
}
)
},
error => {
console.log("์๋ฌ1")
}
)๊ทธ๋ฌ๋ฉด callbackํจ์์ ํ๊ณ๋ฅผ ์ด๋ป๊ฒ ๊ทน๋ณตํ ์ ์์๊น?
๐ callback ํจ์์ ํ๊ณ๋ฅผ ๊ทน๋ณตํ๊ธฐ ์ํ, Promise
Promise๋ ๋ง ๊ทธ๋๋ก ์ฝ์, ์ดํ์ ์ฝ์๋ ๊ฒฐ๊ณผ๋ฅผ ์ฃผ๊ฒ ๋ค๋ ์๋ฏธ๋ฅผ ๊ฐ์ง๋ฉฐ, ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ์ ๊ฒฐ๊ณผ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด๋ค.
promise์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ๋ pending (์ํ๋์ง ์์ ์ํ), fulfilled (์ฑ๊ณต), rejected (์คํจ), ์ธ ๊ฐ์ง๊ฐ ์๊ณ , ์ํ ์ ๋ณด๋ promise๋ฅผ ๋ง๋ค ๋ ์ ๋ฌ ๋ฐ์ ์ธ์์ธ resolve์ reject๋ฅผ ํธ์ถํ๋ฉด์ ๋ณ๊ฒฝ๋๋ค. resolve๋ ์ฑ๊ณต ์์ ์ํํ ํจ์, reject๋ ์คํจ ์์ ์ํํ ํจ์์ด๋ค.
๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋ค์ ํ์ ์ฒ๋ฆฌ๋ฅผ ์ํด์ then, catch, finally ๋ด์ฅ ๋ฉ์๋๋ฅผ ์ด์ฉํ ์ ์์ผ๋ฉฐ, then์ ์ฑ๊ณตํ์ ๋๋ฅผ, catch๋ ์คํจํ์ ๋, finally๋ ์ฑ๊ณต,์คํจ์ ์๊ด์์ด ์ฒ๋ฆฌํ ์ ์๋ค. ๊ฐ๊ฐ์ promise๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์ฒด์ด๋์ด ๊ฐ๋ฅํ๋ค.
์ฒด์ด๋์์ ์ฃผ์ํ ์ ์ ์ฑ๊ณต ์ ๋ฐํํ ๊ฐ์ ๋ค์ then์ ์ธ์๋ก ์ ๋ฌ ๋๊ณ , promise๋ก ๊ณ์ํด์ ์ฒ๋ฆฌ๊ฐ ๋๋ค๋ ์ ์ด๋ค. promise๋ฅผ ์ฒ์ ๋ฐฐ์ธ ๋ ๊ฐ์ฅ ์ด๋ ค์ด ๋ถ๋ถ์ด์๋ค. catch๋ ์ด๋ ๊ณณ์์ ์๋ฌ๊ฐ ๋๋ ๋ฐ์์ค๊ธฐ ๋๋ฌธ์ then์ ๋ ๋ฒ์งธ ์ธ์๋ก ์๋ฌ์ฒ๋ฆฌ๋ฅผ ํ์ง๋ง๊ณ , ํญ์ catch๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ์จ์ ์ด๋ค.
function getData(state) {
return new Promise(function (resolve, reject) {
if (state === "์ฑ๊ณต") {
resolve("์ฑ๊ณต")
} else {
reject(new Error("Request is failed"))
}
})
}
getData("์ฑ๊ณต")
.then(console.log) //์ฑ๊ณต
.catch(function (err) {
console.log(err)
})
getData("์คํจ")
.then(console.log)
.catch(function (err) {
console.log(err) // Error: Request is failed
})๊ทธ๋ฌ๋ฉด ์ด๋ฒ์ ์์ ๋ณด์๋ callback hell ์์ ๋ฅผ promise๋ก ํด๊ฒฐํด๋ณด์
class UserStorage {
loginUser(id, password) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (
(id === "seul" && password === "123") ||
(id === "kim" && password === "456")
) {
resolve(id)
} else {
reject(new Error("์๋ฌ1"))
}
}, 2000)
})
}
getRoles(user) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (user === "seul") {
resolve({ name: "seul", role: "admin" })
} else {
reject(new Error("์๋ฌ2"))
}
}, 1000)
})
}
}
const userStorage = new UserStorage()
const id = prompt("์์ด๋๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์!")
const password = prompt("๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์!!")
userStorage
.loginUser(id, password)
.then(userStorage.getRoles)
.then(user => alert(`hello ${user.name}, you have a ${user.role} role`))
.catch(console.log)ํด๋์ค ๋ด๋ถ๋ ํฌ๊ฒ ๋ฌ๋ผ์ง ๊ฒ์ ์์ง๋ง, ์ฌ์ฉํ ๋ ๋ณต์ก๋๊ฐ ํฌ๊ฒ ์ค์ด ๊ฐ๋ ์ฑ์ด ํฅ์๋ ๊ฒ์ ์ ์ ์๋ค. ์ด๋ ๊ฒ ํ๋ก๋ฏธ์ค๋ฅผ ํตํด callbackํจ์์ ํ๊ณ์ธ ํ์์ฒ๋ฆฌ์ ์๋ฌ์ฒ๋ฆฌ๋ฅผ ํด๊ฒฐํ ์ ์๋ค๋ ๊ฒ์ ์ ์ ์์๋ค.
Promise์ ๋ฉ์๋
promise์ ๋๋ค๋ฅธ ์ฅ์ ์ promise ์์ฒด์ ์ผ๋ก ์ ๊ณตํ๋ ๋ค์ํ ๋ฉ์๋๋ค.
1. Promise.all
์ฌ๋ฌ๊ฐ์ promise๋ฅผ ๋์์ ๋ณ๋ ฌ์ ์ผ๋ก ์ด์ฉํ ๋, ์ฌ์ฉํ ์ ์๋ ๋ฉ์๋๋ก, ์ธ์๋ก ํ๋ก๋ฏธ์ค์ ์ดํฐ๋ฌ๋ธ์ ์ ๋ฌ๋ฐ๋๋ค. ์ ๋ฌ๋ ์ดํฐ๋ฌ๋ธ์ ์์๊ฐ ๋ณด์ฅ๋์ด ๋ฐํ๋๋ฉฐ, ์์์ค ํ๋๋ผ๋ rejected์ํ๊ฐ ๋๋ฉด ๋ฐ๋ก ์ข ๋ฃ๋๋ฉฐ ๊ฐ์ฅ ๋จผ์ rejected๋ ๊ฒฐ๊ณผ๋ฅผ catch๋ก ์ ๋ฌํ๋ค.
์๋์ ์์ ์๋ ์ธ๊ฐ์ง ์๋ก ์์กด๋์ง ์๋ promise๊ฐ ์ํ๋๋๋ฐ. chaining์ ์ด์ฉํด ์ด 6์ด ์ ๋๊ฐ ๊ฑธ๋ฆฌ๋ ์ํฉ์ด๋ค.
const requestData1 = () =>
new Promise(resolve => setTimeout(() => resolve(1), 3000))
const requestData2 = () =>
new Promise(resolve => setTimeout(() => resolve(2), 2000))
const requestData3 = () =>
new Promise(resolve => setTimeout(() => resolve(3), 1000))
const res = []
requestData1()
.then(data => {
//3์ด๋ค ๋ฐ์์
res.push(data)
return requestData2()
})
.then(data => {
//2์ด๋ค ๋ฐ์์
res.push(data)
return requestData3()
})
.then(data => {
//1์ด๋ค ๋ฐ์์
res.push(data)
console.log(data) //์ด 6์ด ๋ค ํธ์ถ
})
.catch(console.log)promise.all์ ์ด์ฉํ๋ฉด ๊ฐ์ฅ ์ค๋ ๊ฑธ๋ฆฌ๋ requestData1์ด fulfilled ์ํ๊ฐ ๋ ๋, ์ด 3์ด ์ ๋๊ฐ ์ง๋๊ณ then์ผ๋ก ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฌ๋์ด ๋ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค.
const requestData1 = () =>
new Promise(resolve => setTimeout(() => resolve(1), 3000))
const requestData2 = () =>
new Promise(resolve => setTimeout(() => resolve(2), 2000))
const requestData3 = () =>
new Promise(resolve => setTimeout(() => resolve(3), 1000))
Promise.all([requestData1(), requestData2(), requestData3()])
.then(console.log) //[1,2,3]
.catch(console.error)2. Promise.race
Promise.race๋ ๋ง ๊ทธ๋๋ก ๊ฒฝ์ฃผํ๋ฏ์ด, ์ ๋ฌ ๋ฐ์ promise ์ค ๊ฐ์ฅ ๋จผ์ fulfilled๋ promise์ ์ฒ๋ฆฌ๊ฒฐ๊ณผ๋ฅผ resolveํ๋ promise๋ฅผ ๋ฐํํ๋ค. ์๋ฌ ์ฒ๋ฆฌ๋ Promise.all๊ณผ ๋์ผํ๊ฒ ์์ ์ค ํ๋๋ผ๋ rejected์ํ๊ฐ ๋๋ฉด ๋ฐ๋ก ์ข ๋ฃ๋๋ฉฐ ๊ฐ์ฅ ๋จผ์ rejected๋ ๊ฒฐ๊ณผ๋ฅผ catch๋ก ์ ๋ฌํ๋ค.
const requestData1 = () =>
new Promise(resolve => setTimeout(() => resolve(1), 3000))
const requestData2 = () =>
new Promise(resolve => setTimeout(() => resolve(2), 2000))
const requestData3 = () =>
new Promise(resolve => setTimeout(() => resolve(3), 1000))
Promise.race([requestData1(), requestData2(), requestData3()])
.then(console.log) //3
.catch(console.error)3. Promise.allSettled
settled์ fulfilled์ด๋ rejected๋ก ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ๋ ์ํ๋ฅผ ์๋ฏธํด ์ฑ๊ณต/์คํจ ์ฌ๋ถ์ ์๊ด์์ด ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด ์ฃผ๋ ๋ฉ์๋๋ค.
Promise.allSettled([
new Promise((resolve) =>
setTimeout(() => {
resolve(1);
}, 2000)
),
new Promise((_, reject) =>
setTimeout(() => {
reject(new Error('error'));
}, 1000)
),
]).then(console.log);
//๊ฒฐ๊ณผ:
[
{ status: 'fulfilled', value: 1 },
{
status: 'rejected',
reason: Error: error
at Timeout._onTimeout (C:\Users\juni2\projects\js study\DeepDive\main.js:32:14)
at listOnTimeout (node:internal/timers:559:17)
at processTimers (node:internal/timers:502:7)
}
]Promise ์ฒ๋ฆฌ๋ microtask Queue
event loop์ ์ค๋ช ํ๋ฉด์ callback์ task queue์ ์ ์ฅ๋๋ค. promise๋ callbackํจ์์ ๋ฌ๋ฆฌ task Queue๊ฐ ์๋ micro-task Queue์ ์ ์ฅ๋๋ค.

microtask queue๋ task queue๋ณด๋ค ์ฐ์ ์์๊ฐ ๋์ callstack์ด ๋น๊ฒ ๋๋ฉด, event loop์ด microtask queue์ promise๋ฅผ ๋ค ๊ฐ์ ธ์ ์ฒ๋ฆฌํ๋ค. ์ด๋ microtask Queue๊ฐ ๋น์ง ์์ผ๋ฉด ๋ค์์ผ๋ก event loop์ด ์ด๋ํ์ง ์๊ณ ๊ณ์ํด์ ๋จธ๋ฌผ๋ฌ์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ฃฝ์ด๋ฒ๋ฆฌ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
function handleClick() {
Promise.resolve(0).then(() => {
handleClick() //์ฌ๊ท๋ก ๊ณ์ํด์ promise๋ฅผ ์ถ๊ฐํด
})
}
handleClick()๋ง์น๋ฉฐ
์๋กญ๊ฒ ์๊ฒ ๋ ๊ฒ์ promise์ then์๊ฒ ๋ ๋ฒ์งธ ์ธ์๋ก ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ๋ด์ ์ค ์ ์๋ค๋ ์ ์ด์๋ค. ํ์ง๋ง catch๋ก ์๋ฌ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ๋ ์ง๊ด์ ์ด๊ณ ํจ์จ์ ์ด๋ผ๋ ์ ๋ ์๊ฒ ๋์๋ค. promise๋ฅผ ์ฌ๋ฌ ๊ฐ ๋์์ ์ฒ๋ฆฌํ ์ ์ด ์์ด์ promise์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด๋ณธ ์ ์ด ์๋ ์์ฌ์์ด ์์๋๋ฐ, ํ์ํ ๋ ๋ ์ฌ๋ฆด ์ ์๊ฒ ๊ณต๋ถํ ๊ฒ์ด ์ข์ ๊ฒฝํ์ด์๋ค.
[์ฐธ์กฐ]