โ๏ธ ์ด๋ฒ ์ ๋ ์ ํตํด ์๊ฒ ๋ ๊ฒ
Promise๊ฐ ๋ฌด์์ธ๊ฐ์?
Promise.all์ ์ธ์ ์ฌ์ฉํ๋์?
<๋ต ๋ฏธ๋ฆฌ๋ณด๊ธฐ>
๐ค Promise๊ฐ ๋ฌด์์ธ๊ฐ์?
๐ค ์๋ฐ์คํฌ๋ฆฝํธ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ํจํด์ผ๋ก ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฌ์ฉํ๋๋ฐ, ์ฝ๋ฐฑ ํจ์๋ ์ฝ๋ฐฑ ํฌ๋ก ๊ฐ๋ ์ฑ์ด ๋์๊ณ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ค ๋ฐ์ํ ์๋ฌ์ ์ฒ๋ฆฌ๊ฐ ๊ณค๋ํ๋ค๋ ํ๊ณ๊ฐ ์์ต๋๋ค. ์ด๋ฅผ ๋ณด์ํ๊ธฐ ์ํด ES6์์ ํ๋ก๋ฏธ์ค๊ฐ ๋์ ๋์ด ์ฝ๋ฐฑ ํจ์์ ๋จ์ ์ ๋ณด์ํ๊ณ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์์ ์ ๋ช ํํ๊ฒ ํํํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
๐ค Promise.all์ ์ธ์ ์ฌ์ฉํ๋์?
๐ค ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฌ์ฉํ์ง ์๋๋ค๋ฉด, ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์, ์ด๋ Promise.all ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ํจํด์ผ๋ก ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฌ์ฉํ๋๋ฐ, ์ฝ๋ฐฑ ํจ์๋ ์ฝ๋ฐฑ ํฌ๋ก ๊ฐ๋ ์ฑ์ด ๋์๊ณ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ค ๋ฐ์ํ ์๋ฌ์ ์ฒ๋ฆฌ๊ฐ ๊ณค๋ํ๊ณ , ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ฒ์ ์ฒ๋ฆฌํ๋๋ฐ๋ ํ๊ณ๊ฐ ์๋ค.
ES6์์ ํ๋ก๋ฏธ์ค๊ฐ ๋์ ๋์ด ์ฝ๋ฐฑ ํจ์์ ๋จ์ ์ ๋ณด์ํ๊ณ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์์ ์ ๋ช ํํ๊ฒ ํํํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.
โ๏ธ ๋น๋๊ธฐ ํจ์์ ๋น๋๊ธฐ ํจ์์ ํน์ง
๋น๋๊ธฐ ํจ์๋ ํจ์ ๋ด๋ถ์ ๋น๋๊ธฐ๋ก ๋์ํ๋ ์ฝ๋๋ฅผ ํฌํจํ ํจ์๋ฅผ ๋งํ๋ค.
๋น๋๊ธฐ ํจ์๋ฅผ ํธ์ถํ๋ฉด ํจ์ ๋ด๋ถ์ ๋น๋๊ธฐ๋ก ๋์ํ๋ ์ฝ๋๊ฐ ์๋ฃ๋์ง ์์๋ค ํด๋ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ ์ข ๋ฃ๋๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ ํจ์ ๋ด๋ถ์ ๋น๋๊ธฐ๋ก ๋์ํ๋ ์ฝ๋์์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ธ๋ถ๋ก ๋ฐํํ๊ฑฐ๋ ์์ ์ค์ฝํ์ ๋ณ์์ ํ ๋นํ๋ฉด ๊ธฐ๋ํ ๋๋ก ๋์ํ์ง ์๋๋ค.
(๋น๋๊ธฐ๋ก ๋์ํ๋ ์ฝ๋๋ ํ์คํฌ ํ์ ์ ์ฅ๋์ด ๋๊ธฐํ๋ค๊ฐ, ์ฝ์คํ์ด ๋น๋ฉด ์ด๋ฒคํธ ๋ฃจํ์ ์ํด ์ฝ ์คํ์ผ๋ก ํธ์๋์ด ์คํ๋๋ค. )
โ๏ธ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋ฐฑ ํจํด์ ๋จ์
1. ์ฝ๋ฐฑํฌ
๋น๋๊ธฐ ํจ์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ธ๋ถ์ ๋ฐํํ ์ ์๊ณ , ์์ ์ค์ฝํ์ ๋ณ์์ ํ ๋นํ ์๋ ์๋ค. ๊ทธ๋์ ๋น๋๊ธฐ ํจ์์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ ๋น๋๊ธฐ ํจ์ ๋ด๋ถ์์ ์ํํด์ผ ํ๋ค.
โฅ ๋น๋๊ธฐ ํจ์๋ฅผ ๋ฒ์ฉ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ํด ๋น๋๊ธฐ ํจ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
๐ ์ฝ๋ฐฑ ํจ์๋ฅผ ํตํด ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ ๋น๋๊ธฐ ํจ์๊ฐ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๊ณ ๋๋ค์ ๋น๋๊ธฐ ํจ์๋ฅผ ํธ์ถํด์ผ ํ๋ค๋ฉด ์ฝ๋ฐฑ ํจ์ ํธ์ถ์ด ์ค์ฒฉ๋์ ๋ณต์ก๋๊ฐ ๋์์ง๋ ํ์์ด ๋ฐ์ํ๋๋ฐ ์ด๋ฅผ ์ฝ๋ฐฑํฌ(callback hell) ์ด๋ผ๊ณ ํ๋ค.
get('/step1', a => {
get(`/step2/${a}`, b => {
get(`/step3/${b}`, c => {
get(`/step4/${c}`, d => {
console.log(d);
});
});
});
});
2. ์๋ฌ ์ฒ๋ฆฌ์ ํ๊ณ
try {
setTimeout(() => { throw new Error('Error!'); }, 1000);
} catch (e) {
// ์๋ฌ๋ฅผ ์บ์นํ์ง ๋ชปํ๋ค
console.error('์บ์นํ ์๋ฌ', e);
}
์๋ฌ๋ ํธ์ถ์ ๋ฐฉํฅ์ผ๋ก ์ ํ๋๋ค.
ํ์ง๋ง setTimeout ํจ์์ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ ๊ฒ์ setTimeout ํจ์๊ฐ ์๋๋ค. (setTimeout ํจ์์ ์ฝ๋ฐฑ ํจ์๊ฐ ์คํ๋ ๋ setTimeout ํจ์๋ ์ด๋ฏธ ์ฝ ์คํ์์ ์ ๊ฑฐ๋ ์ํ์ด๊ธฐ ๋๋ฌธ์!!)
๊ทธ๋์ setTimeout ํจ์์ ์ฝ๋ฐฑ ํจ์๊ฐ ๋ฐ์์ํจ ์๋ฌ๋ catch ๋ธ๋ก์์ ์บ์น๋์ง ์๋๋ค.
โ๏ธ ํ๋ก๋ฏธ์ค : ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด
=> ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋ฐฑ ํจํด์ ์ฝ๋ฐฑ ํฌ์ด๋ ์๋ฌ ์ฒ๋ฆฌ๊ฐ ๊ณค๋ํ๋ค๋ ๋ฌธ์ ๋ฅผ ๊ทน๋ณตํ๊ธฐ ์ํด ES6์์ ํ๋ก๋ฏธ์ค๊ฐ ๋์ ๋์๋ค.
Promise ์์ฑ์ ํจ์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํํ ์ฝ๋ฐฑ ํจ์๋ก resolve์ reject ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ ๋ฐ๋๋ค.
๋น๋๊ธฐ ์ฒ๋ฆฌ ์ฑ๊ณต์ → resolve ํจ์ ํธ์ถ
๋น๋๊ธฐ ์ฒ๋ฆฌ ์คํจ์ → reject ํจ์ ํธ์ถ
- ํ๋ก๋ฏธ์ค์ ์ํ ์ ๋ณด
ํ๋ก๋ฏธ์ค์ ์ํ ์ ๋ณด | ์๋ฏธ | ์ํ ๋ณ๊ฒฝ ์กฐ๊ฑด |
pending | ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์์ง ์ํ๋์ง ์์ ์ํ | ํ๋ก๋ฏธ์ค๊ฐ ์์ฑ๋ ์งํ ๊ธฐ๋ณธ ์ํ |
fulfilled | ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ํ๋ ์ํ(์ฑ๊ณต) | resolve ํจ์ ํธ์ถ |
rejected | ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ํ๋ ์ํ(์คํจ) | reject ํจ์ ํธ์ถ |
// fulfilled๋ ํ๋ก๋ฏธ์ค
const fulfilled = new Promise(resolve => resolve(1));
// rejected๋ ํ๋ก๋ฏธ์ค
const rejected = new Promise((_, reject) => reject(new Error('error occurred')));
โ๏ธ ํ๋ก๋ฏธ์ค์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋
ํ๋ก๋ฏธ์ค์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ๊ฐ ๋ณํํ๋ฉด ์ด์ ๋ฐ๋ฅธ ํ์ ์ฒ๋ฆฌ๋ฅผ ํด์ผํ๋ค.
1. Promise.prototype.then
then ๋ฉ์๋๋ ๋ ๊ฐ์ ์ฝ๋ฐฑ ํจ์(์ฑ๊ณต ์ฒ๋ฆฌ ์ฝ๋ฐฑ ํจ์, ์คํจ ์ฒ๋ฆฌ ์ฝ๋ฐฑ ํจ์)๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๋๋ค.
2. Promise.prototype.catch
catch ๋ฉ์๋๋ ํ ๊ฐ์ ์ฝ๋ฐฑ ํจ์(ํ๋ก๋ฏธ์ค๊ฐ rejected ์ํ์ธ ๊ฒฝ์ฐ)๋ฅผ ์ธ์๋ก ์ ๋ฌ ๋ฐ๋๋ค.
catch ๋ฉ์๋๋ then๊ณผ ๋์ผํ๊ฒ ๋์ํ๋ค.
3. Promise.prototype.finally
finally ๋ฉ์๋๋ ํ ๊ฐ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ ๋ฐ๋๋ค.
finally ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์๋ ํ๋ก๋ฏธ์ค์ ์ฑ๊ณต ๋๋ ์คํจ์ ์๊ณผ์์ด ๋ฌด์กฐ๊ฑด ํ ๋ฒ ํธ์ถ๋๋ค.
๐ finally ๋ฉ์๋๋ ํ๋ก๋ฏธ์ค์ ์ํ์ ์๊ด์์ด ๊ณตํต์ ์ผ๋ก ์ํํด์ผ ํ ์ฒ๋ฆฌ ๋ด์ฉ์ด ์์ ๋ ์ ์ฉํ๋ค.
const promiseGet = url => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
xhr.onload = () => {
if (xhr.status === 200) {
// ์ฑ๊ณต์ ์ผ๋ก ์๋ต์ ์ ๋ฌ๋ฐ์ผ๋ฉด resolve ํจ์๋ฅผ ํธ์ถํ๋ค.
resolve(JSON.parse(xhr.response));
} else {
// ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด reject ํจ์๋ฅผ ํธ์ถํ๋ค.
reject(new Error(xhr.status));
}
};
});
};
// promiseGet ํจ์๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
promiseGet('https://jsonplaceholder.typicode.com/posts/1')
.then(res => console.log(res))
.catch(err => console.error(err))
.finally(() => console.log('Bye!'));
//์ฃผ์๋ฅผ ์ผ๋ถ๋ฌ ์๋ชป ์จ๋ด
promiseGet('https://jsonplaceholder.typicode.com/post/1')
.then(res => console.log(res))
.catch(err => console.error(err))
.finally(() => console.log('Bye!'));
โ๏ธ ํ๋ก๋ฏธ์ค์ ์๋ฌ ์ฒ๋ฆฌ
ํ๋ก๋ฏธ์ค์ ์๋ฌ์ฒ๋ฆฌ๋ ์ฃผ๋ก catch ๋ฉ์๋๋ก ์ฌ์ฉํ๋๋ฐ, catch ๋ฉ์๋๋ฅผ ๋ชจ๋ then ๋ฉ์๋๋ฅผ ํธ์ถํ ์ดํ์ ํธ์ถํ๋ฉด ๋น๋๊ธฐ ์ฒ๋ฆฌ์์ ๋ฐ์ํ ์๋ฌ์ then ๋ฉ์๋ ๋ด๋ถ์์ ๋ฐ์ํ ์๋ฌ๊น์ง ๋ชจ๋ ์บ์นํ ์ ์๋ค.
โ๏ธ ํ๋ก๋ฏธ์ค ์ฒด์ด๋
์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํด์ผ ํ๋ ๋น๋๊ธฐ ์์ ์ด ์ฌ๋ฌ ๊ฐ ์๋ค๋ฉด ํ๋ผ๋ฏธ์ค ์ฒด์ด๋(promise chaining)์ ์ด์ฉํด์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ ๊ฒฝ์ฐ๋ ์๋ค.
ํ๋ก๋ฏธ์ค ์ฒด์ด๋์ด ๊ฐ๋ฅํ ์ด์ ๋ promise.then์ ํธ์ถํ๋ฉด ํ๋ผ๋ฏธ์ค๊ฐ ๋ฐํ๋๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐํ๋ ํ๋ผ๋ฏธ์ค์ ๋น์ฐํ .then์ ํธ์ถํ ์ ์๋ค.
- ์ฝ๋ฐฑ ํจ์ ์ฌ์ฉ
// GET ์์ฒญ์ ์ํ ๋น๋๊ธฐ ํจ์
const get = (url, callback) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
xhr.onload = () => {
if (xhr.status === 200) {
// ์๋ฒ์ ์๋ต์ ์ฝ๋ฐฑ ํจ์์ ์ ๋ฌํ๋ฉด์ ํธ์ถํ์ฌ ์๋ต์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
callback(JSON.parse(xhr.response));
} else {
console.error(`${xhr.status} ${xhr.statusText}`);
}
};
};
const url = 'https://jsonplaceholder.typicode.com';
// id๊ฐ 1์ธ post์ userId๋ฅผ ์ทจ๋
get(`${url}/posts/1`, ({ userId }) => {
console.log(userId); // 1
// post์ userId๋ฅผ ์ฌ์ฉํ์ฌ user ์ ๋ณด๋ฅผ ์ทจ๋
get(`${url}/users/${userId}`, userInfo => {
console.log(userInfo); // {id: 1, name: "Leanne Graham", username: "Bret",...}
});
});
- promise ์ฌ์ฉ
const url = 'https://jsonplaceholder.typicode.com';
// id๊ฐ 1์ธ post์ userId๋ฅผ ์ทจ๋
promiseGet(`${url}/posts/1`)
// ์ทจ๋ํ post์ userId๋ก user ์ ๋ณด๋ฅผ ์ทจ๋
.then(({ userId }) => promiseGet(`${url}/users/${userId}`))
.then(userInfo => console.log(userInfo))
.catch(err => console.error(err));
- async/await ์ฌ์ฉ
const url = 'https://jsonplaceholder.typicode.com';
(async () => {
// id๊ฐ 1์ธ post์ userId๋ฅผ ์ทจ๋
const { userId } = await promiseGet(`${url}/posts/1`);
// ์ทจ๋ํ post์ userId๋ก user ์ ๋ณด๋ฅผ ์ทจ๋
const userInfo = await promiseGet(`${url}/users/${userId}`);
console.log(userInfo);
})();
โ๏ธ Promise.all
Promise.all ๋ฉ์๋๋ ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ชจ๋ ๋ณ๋ ฌ ์ฒ๋ฆฌํ ๋ ์ฌ์ฉํ๋ค.
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 => {
res.push(data);
return requestData2();
})
.then(data => {
res.push(data);
return requestData3();
})
.then(data => {
res.push(data);
console.log(res); // [1, 2, 3] ⇒ ์ฝ 6์ด ์์
})
.catch(console.error);
โฅ ์ธ ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ค. ๊ทธ๋์ ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋๋ฉด ๋ค์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ค.
์ฒซ๋ฒ์งธ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ 3์ด, ๋๋ฒ์งธ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ 2์ด, ์ธ๋ฒ์งธ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ 1์ด๊ฐ ์์๋์ ์ด 6์ด ์ด์์ด ์์๋๋ค.
์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฌ์ฉํ์ง ์๋๋ค๋ฉด, ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํ ํ์๊ฐ ์๋ค. ์ด๋ Promise.all ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
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 ] ⇒ ์ฝ 3์ด ์์
.catch(console.error);
โฅ ์ฒซ๋ฒ์งธ ํ๋ก๋ฏธ์ค๋ 3์ด ํ์ 1์ resolveํ๊ณ , ๋๋ฒ์งธ ํ๋ก๋ฏธ์ค๋ 2์ด ํ์ 2์ resolveํ๊ณ , ์ธ๋ฒ์งธ ํ๋ก๋ฏธ์ค๋ 1์ด ํ์ 3์ resolveํด์ ์ด 3์ด ์ด์์ด ์์๋๋ค.
Promise.all ๋ฉ์๋๋ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ฐฐ์ด์ ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ ๋ชจ๋ fulfulled ์ํ๊ฐ ๋๋ฉด ์ข ๋ฃํ๋ค.
Promise.all ๋ฉ์๋๋ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ฐฐ์ด์ ํ๋ก๋ฏธ์ค๊ฐ ํ๋๋ผ๋ rejected ์ํ๊ฐ ๋๋ฉด ๋๋จธ์ง ํ๋ก๋ฏธ์ค๊ฐ fulfilled ์ํ๊ฐ ๋๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ ์ข ๋ฃํ๋ค.
Promise.all([
new Promise((_, reject) => setTimeout(() => reject(new Error('Error 1')), 3000)),
new Promise((_, reject) => setTimeout(() => reject(new Error('Error 2')), 2000)),
new Promise((_, reject) => setTimeout(() => reject(new Error('Error 3')), 1000))
])
.then(console.log)
.catch(console.log); // Error: Error 3