๐ Promise.allSettled ์ Promise.all ๋น๊ต ์ ๋ฆฌ
Promise.all ์ ๋ฌธ์ ์
Promise.all([ promise1, promise2, ... ]) ์ ํํ๋ก ์ฌ์ฉ๋๋ฉฐ, ๋ฐฐ์ด๋ก ๋ฐ์ ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ fulfill ๋ ์ดํ, ๋ชจ๋ ํ๋ก๋ฏธ์ค์ ๋ฐํ ๊ฐ์ ๋ฐฐ์ด์ ๋ฃ์ด ๋ฐํํ๋ค.
๊ทธ๋ฐ๋ฐ ๋ง์ฝ ๋ฐฐ์ด์ ์๋ ํ๋ก๋ฏธ์ค ์ค ํ๋๋ผ๋ reject๊ฐ ํธ์ถ๋๋ค๋ฉด, ์ฑ๊ณตํ ํ๋ก๋ฏธ์ค ์๋ต์ ๋ฌด์๋์ฑ๋ก ๊ทธ๋ฅ ๋ฐ๋ก catch๋ก ๋น ์ ธ๋ฒ๋ฆฌ๊ฒ ๋๋ค.
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve(1);
}, 3000);
});
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve(2);
}, 2000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('๋ค ๋ฌด์ํ๊ณ ์๋ฌ๋ด๋ฒ๋ ค!'));
}, 2500);
});
Promise.all([promise1, promise2, promise3])
.then((result) => console.log(result))
.catch((e) => console.error(e));
์์ ์์ ๋ ๋จ์ํ ์ฝ๋๋ผ ์ ์๋ฟ์ง ์๊ฒ ์ง๋ง, ๋ค์๊ณผ ๊ฐ์ด ๋น๋๊ธฐ api๋ก ์๋ฒ์ ์์ฒญ์ ๋ณด๋ธ๋ค๊ณ ๊ฐ์ ํด๋ณด์.
const req1 = axios.post('์๋ฒ์ฃผ์', { obj1 });
const req2 = axios.post('์๋ฒ์ฃผ์', { obj2 });
const req3 = axios.post('์๋ฒ์ฃผ์', { obj3 });
const req4 = axios.post('์๋ฒ์ฃผ์', { obj4 });
const req5 = axios.post('์๋ฒ์ฃผ์', { obj5 });
Promise.all([req1, req2, req3, req4, req5])
.then((result) => console.log(result))
.catch((err) => console.log(err));
์์ฒ๋ผ ํ๋ฒ์ ๋๋ฌด ๋ง์ Request ๋ฅผ ์๋ฒ์ ๋ ๋ฆฌ๊ฒ ๋๋ฉด ์๋ฒ์ ๊ณผ๋ถํ๋ฅผ ์ค ์ ์๋ค.
๊ทธ๋์ ๋ง์ผ ๋๋จธ์ง ์์ฒญ์ ๋ฌธ์ ์์ด ์ ๋ฌ๋๋ฐ, req3 ์์ฒญ๋ง ์๋ฌ๊ฐ ์๊ฒจ reject๋์๋ค๊ณ ๊ฐ์ ํ์.๊ทธ๋ฌ๋ฉด ๋ค์ ์์ฒญ์ ๋ณด๋ด์ผ ๋๋๋ฐ, ๋ req 1 ~ 5 ๊ฐ์ ์์ฒญ์ ํ๊บผ๋ฒ์ ๋ณด๋ด์ผ ๋๋ค. ์คํจํ req3 ์์ฒญ๋ง ๋ค์ ๋ณด๋ด์ ์๋ต ๋ฐ์ผ๋ฉด ๋์ง ๋นํจ์จ์ ์ผ๋ก ์์ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ์๋ ๊ฒ์ด๋ค.
Promise.allSettled
Promise.all์ ๊ฒฝ์ฐ, ํ๋์ ํ๋ก๋ฏธ์ค๋ผ๋ ์คํจํ๋ฉด ์๋ฌ๋ก ์ฒ๋ฆฌ๋์๋ค.
๋ฐ๋ฉด, Promise.allSettled๋ ์ฌ๋ฌ ํ๋ก๋ฏธ์ค๋ฅผ ๋ณ๋ ฌ์ ์ผ๋ก ์ฒ๋ฆฌํ๋, ํ๋์ ํ๋ก๋ฏธ์ค๊ฐ ์คํจํด๋ ๋ฌด์กฐ๊ฑด ์ดํํ๋ค.
Promise.allSettled([ promise1, promise2,...]) ์ ํํ๋ก ์ด ์ญ์ Promise.all๊ณผ ๋์ผํ ํํ๋ก ์คํํ๋ค. ํ์ง๋ง ๋ฐํ๊ฐ์ Promise.all๊ณผ ๋งค์ฐ ๋ค๋ฅด๋ค.
๋ฐฐ์ด๋ก ๋ฐ์ ๋ชจ๋ ํ๋ก๋ฏธ์ค์ fulfilled, reject ์ฌ๋ถ์ ์๊ด์์ด, ์ ๋ถ ์๋ฃ๋ง ๋์๋ค๋ฉด(not pending) ํด๋น ํ๋ก๋ฏธ์ค๋ค์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์ด๋ก ๋ฆฌํดํ๋ค.
์์์ ํ๋ Promise.all ์ฝ๋๋ฅผ Promise.allSettled ๋ก ๋ฐ๊ฟ๋ณด์.
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve(1);
}, 3000);
});
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve(2);
}, 2000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('๋ค ๋ฌด์ํ๊ณ ์๋ฌ๋ด๋ฒ๋ ค!'));
}, 2500);
});
Promise.allSettled([promise1, promise2, promise3])
.then((result) => console.log(result))
.catch((e) => console.error(e));
์์๊ฐ์ด ๋ฐฐ์ด์ status์ value ์์ฑ์ ๋ด์ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ฃผ๋ ๊ฑธ ๋ณผ ์ ์๋ค.
์ฑ๊ณตํ๋ฉด status ํ๋์ fulfilled(์ดํ๋) ๊ฐ์ ๋ฃ๊ณ , ์คํจํ๋ฉด rejected(๊ฑฐ๋ถ๋) ๊ฐ์ ๋ฃ๋๋ค.
์ด์ ์ด ๋ฐฐ์ด์ ์ํํด์ ๊ฐ์ ์ป์ผ๋ฉด ๋๋ ๊ฒ์ด๋ค.
์ด์ ์๋ฒ ์์ฒญ Promise.all์ ๋ค์๊ณผ ๊ฐ์ด ์คํจํ๊ฒ๋ค๋ง ๋ฐ๋ก ํํฐ๋งํด์ ์ฌ์์ฒญ ๋ณด๋ด๋ ์์ผ๋ก ์์ฉํ ์ ์๊ฒ ๋์๋ค.
const req1 = axios.post('์๋ฒ์ฃผ์', { obj1 });
const req2 = axios.post('์๋ฒ์ฃผ์', { obj2 });
const req3 = axios.post('์๋ฒ์ฃผ์', { obj3 });
const req4 = axios.post('์๋ฒ์ฃผ์', { obj4 });
const req5 = axios.post('์๋ฒ์ฃผ์', { obj5 });
const postArr = [req1, req2, req3, req4, req5];
Promise.allSettled(postArr)
.then((result) => {
// ์คํจํ ๊ฒ๋ค๋ง ํํฐ๋งํด์ ๋ค์ ์๋
result.forEach(async (val, index) => {
if(val.status === 'rejected') {
await postArr[index]; // ์คํจํ ์์ฒญ ๋ค์ ajax
}
})
})
.catch((err) => console.log(err));
Promise.allSettled ํด๋ฆฌํ
๊ทธ๋ ๋ค๊ณ ๋๋ฌด Promise.allSettled ๋ฅผ ๋งน๋ชฉ์ ์ผ๋ก ๋ฏฟ๊ณ ์ฌ์ฉํ๋ฉด ์๋๋ค.
Promise.all ์ ์์ํธํ์ด ์๋ ํธ์์ฑ์ ์ํด ๊ตฌํ๋ ๊ธฐ๋ฅ์ด๊ธฐ ๋๋ฌธ์ ํ์ํ ๊ธฐ๋ฅ์ ์ ์ ํ ํ๋จ์ผ๋ก ์ ์ฌ์ ์์ ์ฌ์ฉํ๋๊ฒ ์ข๋ค. ๊ทธ๋ฆฌ๊ณ ์์ง ํ์ค์ ๋ฑ์ ๋์ง ์ผ๋ง๋์ง ์์ ๋ฐ๋๋ฐ๋ํ ๊ธฐ๋ฅ์ด๋ผ, ๊ตฌํ ๋ธ๋ผ์ฐ์ ๋ LTS ๋ฒ์ ผ Node.js ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด Pollyfill ๋ฅผ ๋ฐ๋ก ๊ตฌํ ํด์ค์ผ ํ๋ค.
/* ํด๋ฆฌํ ์ฝ๋ */
if(!Promise.allSettled) {
Promise.allSettled = function(promises) {
return Promise.all(promises.map(p => Promise.resolve(p).then(value => ({
status: 'fulfilled',
value
}), reason => ({
status: 'rejected',
reason
}))));
};
}
#์ฐธ๊ณ ์๋ฃ
https://dmitripavlutin.com/promise-all/
https://twitter.com/mgechev/status/1300682318114361345