Language/JavaScript

๐Ÿ“š Promise.allSettled ์™€ Promise.all ๋น„๊ต ์ •๋ฆฌ

์ธํŒŒ_ 2022. 7. 22. 09:45

Promise.allSettled

Promise.all ์˜ ๋ฌธ์ œ์ 

Promise.all([ promise1, promise2, ... ]) ์˜ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉ๋˜๋ฉฐ, ๋ฐฐ์—ด๋กœ ๋ฐ›์€ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ fulfill ๋œ ์ดํ›„, ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๋ฐฐ์—ด์— ๋„ฃ์–ด ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ๋ฐฐ์—ด์— ์žˆ๋Š” ํ”„๋กœ๋ฏธ์Šค ์ค‘ ํ•˜๋‚˜๋ผ๋„ reject๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค๋ฉด, ์„ฑ๊ณตํ•œ ํ”„๋กœ๋ฏธ์Šค ์‘๋‹ต์€ ๋ฌด์‹œ๋œ์ฑ„๋กœ ๊ทธ๋ƒฅ ๋ฐ”๋กœ catch๋กœ ๋น ์ ธ๋ฒ„๋ฆฌ๊ฒŒ ๋œ๋‹ค.

Promise.all

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));

Promise.all

 

์œ„์˜ ์˜ˆ์ œ๋Š” ๋‹จ์ˆœํ•œ ์ฝ”๋“œ๋ผ ์ž˜ ์™€๋‹ฟ์ง€ ์•Š๊ฒ ์ง€๋งŒ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋น„๋™๊ธฐ 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
Settled๋ž€ ์•ˆ์ •๋œ์ด๋ผ๋Š” ์˜๋ฏธ์ด๋‹ค.

Promise.allSettled([ promise1, promise2,...]) ์˜ ํ˜•ํƒœ๋กœ ์ด ์—ญ์‹œ Promise.all๊ณผ ๋™์ผํ•œ ํ˜•ํƒœ๋กœ ์‹คํ–‰ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๋ฐ˜ํ™˜๊ฐ’์€ Promise.all๊ณผ ๋งค์šฐ ๋‹ค๋ฅด๋‹ค.

๋ฐฐ์—ด๋กœ ๋ฐ›์€ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค์˜ fulfilled, reject ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด, ์ „๋ถ€ ์™„๋ฃŒ๋งŒ ๋˜์—ˆ๋‹ค๋ฉด(not pending) ํ•ด๋‹น ํ”„๋กœ๋ฏธ์Šค๋“ค์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฆฌํ„ดํ•œ๋‹ค.

Promise.allSettled

 

์•ž์—์„œ ํ–ˆ๋˜ 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));

Promise.allSettled

์œ„์™€๊ฐ™์ด ๋ฐฐ์—ด์— status์™€ value ์†์„ฑ์„ ๋‹ด์‘ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์„ฑ๊ณตํ•˜๋ฉด status ํ•„๋“œ์— fulfilled(์ดํ–‰๋œ) ๊ฐ’์„ ๋„ฃ๊ณ , ์‹คํŒจํ•˜๋ฉด rejected(๊ฑฐ๋ถ€๋œ) ๊ฐ’์„ ๋„ฃ๋Š”๋‹ค.

์ด์ œ ์ด ๋ฐฐ์—ด์„ ์ˆœํšŒํ•ด์„œ ๊ฐ’์„ ์–ป์œผ๋ฉด ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

Promise.allSettled

 

์ด์ œ ์„œ๋ฒ„ ์š”์ฒญ 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