๋ฐ˜์‘ํ˜•

TL;DR


๐Ÿ’ก ์ฒ˜๋ฆฌ(settled) ์ƒํƒœ๋Š” ์ดํ–‰(fulfilled) ๋˜๋Š” ๊ฑฐ์ ˆ(rejected) ์ƒํƒœ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•œ๋‹ค.

 

  • Promise.all : ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ดํ–‰๋˜์–ด์•ผ๋งŒ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ๊ฑฐ์ ˆ๋˜๋ฉด ์ „์ฒด๊ฐ€ ๊ฑฐ์ ˆ๋œ๋‹ค.
  • Promise.allSettled : ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ฒ˜๋ฆฌ(์ดํ–‰ ๋˜๋Š” ๊ฑฐ์ ˆ)๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • Promise.race : ๊ฐ€์žฅ ๋จผ์ € ์ฒ˜๋ฆฌ(์ดํ–‰ ํ˜น์€ ๊ฑฐ์ ˆ) ์ƒํƒœ๊ฐ€ ๋œ ํ”„๋กœ๋ฏธ์Šค ์ฒ˜๋ฆฌ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • Promise.any : ํ”„๋กœ๋ฏธ์Šค ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์ดํ–‰๋˜๋ฉด ํ•ด๋‹น ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๊ฑฐ์ ˆ๋˜๋ฉด ๊ฑฐ์ ˆ ์ด์œ ๋ฅผ ๋‹ด์€ AggregateError๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

 

Promise.all


๐Ÿ’ก ํ”„๋กœ๋ฏธ์Šค ํ›„์† ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•œ ์ฒด์ด๋‹์€ ์ˆœ์ฐจ์  ์ฒ˜๋ฆฌ, Promise.all์€ ๋ณ‘๋ ฌ(๋™์‹œ) ์ฒ˜๋ฆฌ ์ฐจ์ด์  ๊ธฐ์–ต. Promise.all์€ ๋งˆ์ง€๋ง‰ ์ดํ–‰(fulfilled) ์ƒํƒœ๊ฐ€ ๋œ ํ”„๋กœ๋ฏธ์Šค์˜ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„๋ณด๋‹ค ์กฐ๊ธˆ ๋” ๊ธธ๋‹ค.

 

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

Promise.all ๋ฉ”์„œ๋“œ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋™์‹œ์— ์‹คํ–‰์‹œํ‚ค๊ณ , ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ fulfilled(์ดํ–‰) ์ƒํƒœ๊ฐ€ ๋œ ํ›„ ์ž‘์—…์„ ์ฒ˜๋ฆฌ ํ•ด์•ผํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

Promise.all ๋ฉ”์„œ๋“œ๋Š” ์ฒ˜๋ฆฌ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๋ฉฐ, ์ „๋‹ฌ๋ฐ›์€ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ 1๊ฐœ๋ผ๋„ rejected ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ๋‚˜๋จธ์ง€ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ดํ–‰ ์ƒํƒœ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ์ข…๋ฃŒํ•˜๋Š” ํŠน์ง•์ด ์žˆ๋‹ค.

// Promise.all ๊ธฐ๋ณธ ๊ตฌ๋ฌธ
const promise = Promise.all([promise1, promise2, ...]);

// then ๋Œ€์‹  Promise.all ์•ž์— await ํ‚ค์›Œ๋“œ ๋ถ™์—ฌ์„œ ๊ฒฐ๊ณผ๊ฐ’์„ results ๋ณ€์ˆ˜์— ์ €์žฅ
const results = await Promise.all([promise1, promise2, ...]); // [...]
const [res1, res2] = await Promise.all([promise1, promise2, ...]); // [...]

 

Promise.all ๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์š”์†Œ๋กœ ๊ฐ–๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”(๋ฐฐ์—ด, ๋ฌธ์ž์—ด ๋“ฑ)์„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›์€ ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ์š”์†Œ๊ฐ€ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์•„๋‹ˆ๋ฉด, ์•”๋ฌต์ ์œผ๋กœ Promise.resolve ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ํ”„๋กœ๋ฏธ์Šค๋กœ ๋ž˜ํ•‘ํ•œ๋‹ค.

Promise.all([
  1, // Promise.resolve(1) ์™€ ๋™์ผ
  2, // Promise.resolve(2) ์™€ ๋™์ผ
]).then(console.log); // [1, 2]

 

Promise.all์€ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›์€ ๋ฐฐ์—ด์˜ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ fulfilled ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ์ข…๋ฃŒ๋œ๋‹ค. ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ fullfilled ์ƒํƒœ๊ฐ€ ๋˜๋ฉด resolved๋œ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด์— ์ €์žฅํ•˜์—ฌ ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. Promise.all์€ ์ฒ˜๋ฆฌ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๋Š” ํŠน์ง•์ด ์žˆ๋‹ค. ์ฆ‰, ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ ๋ฐฐ์—ด์€ ํ•ญ์ƒ Promise.all ์ธ์ž์— ์ „๋‹ฌํ•œ ์ˆœ์„œ์™€ ๊ฐ™๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ์ฒซ๋ฒˆ์งธ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๊ฐ€์žฅ ๋Šฆ๊ฒŒ fulfilled ๋์–ด๋„ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ ๋ฐฐ์—ด์—” ํ•ญ์ƒ ์ฒซ๋ฒˆ์งธ ์š”์†Œ์— ์œ„์น˜ํ•œ๋‹ค.

Promise.all([
  new Promise((resolve) => setTimeout(() => resolve(1), 5000)), // 3๋ฒˆ์งธ ์ดํ–‰
  new Promise((resolve) => setTimeout(() => resolve(2), 3000)), // 2๋ฒˆ์งธ ์ดํ–‰
  new Promise((resolve) => setTimeout(() => resolve(3), 1000)), // 1๋ฒˆ์งธ ์ดํ–‰
]).then(console.log); // ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋ฉด [1, 2, 3] ์ถœ๋ ฅ

 

Promise.all์ด ์ธ์ž๋กœ ๋ฐ›์€ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ํ•˜๋‚˜๋ผ๋„ rejected ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ๋‚˜๋จธ์ง€ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ fulfilled ์ƒํƒœ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ์ข…๋ฃŒํ•œ๋‹ค. ์ฆ‰, 1๊ฐœ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๊ฑฐ์ ˆ๋˜๋ฉด Promise.all ์ „์ฒด๊ฐ€ ๊ฑฐ์ ˆ๋˜๊ณ  ์ดํ–‰๋œ ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ๋„ ๋ฌด์‹œ๋œ๋‹ค. ์ด๋•Œ ๊ฐ€์žฅ ๋จผ์ € ๊ฑฐ์ ˆ๋œ ํ”„๋กœ๋ฏธ์Šค์˜ ์—๋Ÿฌ๊ฐ€ catch ๋ฉ”์„œ๋“œ๋กœ ์ „๋‹ฌ๋˜๋ฉฐ, Promise.all ์ „์ฒด์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋œ๋‹ค.

 

์—๋Ÿฌ ๋ฐœ์ƒ์œผ๋กœ ์ „์ฒด Promise.all์ด ์ข…๋ฃŒ๋˜๋Š” ์ƒํ™ฉ โ–ผ

Promise.all([
  new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
  new Promise((resolve, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 2')), 2000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000)),
])
  .then(console.log) // ๊ฑด๋„ˆ๋œ€
  .catch(console.error); // Error: ์—๋Ÿฌ 2 (์—๋Ÿฌ ๋ฐœ์ƒํ–ˆ์œผ๋ฏ€๋กœ Promise.all ์ข…๋ฃŒ)

 

์—ฌ๋Ÿฌ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ โ–ผ

Promise.all([
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 1')), 5000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 2')), 3000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 3')), 1000)),
])
  .then(console.log) // ๊ฑด๋„ˆ๋œ€
  .catch(console.error); // Error: ์—๋Ÿฌ 3 (๊ฐ€์žฅ ๋จผ์ € ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ํ”„๋กœ๋ฏธ์Šค)

 

ํ™œ์šฉ ์˜ˆ์‹œ โญ๏ธ

์—ฌ๋Ÿฌ ์ž‘์—…์„ ํ”„๋กœ๋ฏธ์Šค๋กœ ๊ตฌ์„ฑ๋œ ๋ฐฐ์—ด๋กœ ๋งŒ๋“  ํ›„ Promise.all์„ ์ด์šฉํ•ด ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌํ•˜๋Š” ์˜ˆ์‹œ

 

map ๊ฐ™์€ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ ์ฝœ๋ฐฑ์— async, await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์—ฌ์ „ํžˆ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋Š” ๊ฐ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœํ•˜๊ณ  ์ข…๋ฃŒ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ๋‹ค์Œ ์ฝœ๋ฐฑ์„ ์‹คํ–‰์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ฆ‰, ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์ž์ฒด๋Š” ๋™๊ธฐ๋กœ ์ž‘๋™ํ•˜์ง€๋งŒ ๊ฐ ์ฝœ๋ฐฑ์€ ๋น„๋™๊ธฐ๋กœ ์‹คํ–‰์‹œํ‚จ๋‹ค.

 

์ž˜๋ชป๋œ ์˜ˆ์‹œ โŒ

const baseUrl = 'https://api.github.com/users';
const urls = [`${baseUrl}/iliakan`, `${baseUrl}/remy`, `${baseUrl}/jeresig`];

// requests -> [Promise, Promise, Promise]
const requests = urls.map(async (url) => await fetch(url));

 

์˜ฌ๋ฐ”๋ฅธ ์˜ˆ์‹œ โœ…

const baseUrl = 'https://api.github.com/users';
const urls = [`${baseUrl}/iliakan`, `${baseUrl}/remy`, `${baseUrl}/jeresig`];

// fetch API๋ฅผ ์ด์šฉํ•ด url์„ ํ”„๋กœ๋ฏธ์Šค๋กœ ๋งคํ•‘
// fetch API๋Š” HTTP ์‘๋‹ต์„ ๋‚˜ํƒ€๋‚ด๋Š” Response ๊ฐ์ฒด๋ฅผ ๋ž˜ํ•‘ํ•œ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค
// requests -> [Promise, Promise, Promise]
const requests = urls.map(url => fetch(url));

// Promise.all์€ ๋ชจ๋“  ์ž‘์—…์ด ์ดํ–‰๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„,
// ๊ฐ ์š”์†Œ์˜ ํ”„๋กœ๋ฏธ์Šค ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด์— ์ €์žฅํ•ด ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค
Promise.all(requests)
  // ๋ชจ๋“  ์‘๋‹ต์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ดํ–‰๋˜๋ฉด then ๋ฉ”์„œ๋“œ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ ,
  // ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์ธ์ž์—” ํ”„๋กœ๋ฏธ์Šค ์ฒ˜๋ฆฌ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ(๋ฐฐ์—ด)๋ฅผ ์ „๋‹ฌํ•œ๋‹ค
  .then(responses => // [Response, Response, Response]
    responses.forEach(response => // Response {type: 'cors', url: '...', status: 200, ...}
      console.log(`${response.url}: ${response.status}`),
    ),
  );

 

GitHub ์œ ์ € ๋„ค์ž„์ด ๋‹ด๊ธด ๋ฐฐ์—ด์„ ์ด์šฉํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์˜ˆ์‹œ โ–ผ

const baseUrl = 'https://api.github.com/users';
const names = ['iliakan', 'remy', 'jeresig'];

// fetch API๋Š” HTTP ์‘๋‹ต์„ ๋‚˜ํƒ€๋‚ด๋Š” Response ๊ฐ์ฒด๋ฅผ ๋ž˜ํ•‘ํ•œ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค
// requests -> [Promise, Promise, Promise]
const requests = names.map((name) => fetch(`${baseUrl}/${name}`));

// Promise.all์€ ๋ชจ๋“  ์ž‘์—…์ด ์ดํ–‰๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„
// ๊ฐ ์š”์†Œ์˜ ํ”„๋กœ๋ฏธ์Šค ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด์— ์ €์žฅํ•ด ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค
Promise.all(requests)
  // ๋ชจ๋“  ์‘๋‹ต์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ดํ–‰๋˜๋ฉด then ๋ฉ”์„œ๋“œ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ ,
  // ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์ธ์ž์—” ํ”„๋กœ๋ฏธ์Šค ์ฒ˜๋ฆฌ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ(๋ฐฐ์—ด)๋ฅผ ์ „๋‹ฌํ•œ๋‹ค
  .then((responses) => {
    // [Response, Response, Response]
    for (const response of responses) {
      console.log(`${response.url}: ${response.status}`);
      // 'https://api.github.com/users/iliakan: 200', ...
    }
    return responses;
  })
  // Response ๊ฐ์ฒด์— ์žˆ๋Š” json() ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด body ๋‚ด์šฉ์„ JSON ํ˜•ํƒœ๋กœ ํŒŒ์‹ฑํ•œ๋‹ค
  .then((responses) => Promise.all(responses.map((r) => r.json())))
  // ํŒŒ์‹ฑ๋œ ๊ฐ ๊ฐ์ฒด๊ฐ€ ๋‹ด๊ธด ๋ฐฐ์—ด์€ then ๋ฉ”์„œ๋“œ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์ธ์ž(users)๋กœ ์ „๋‹ฌ๋œ๋‹ค.
  .then((users) => users.forEach((user) => console.log(user.name)));

 

์•„๋ž˜์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ข€ ๋” ๊ฐ„์†Œํ™”ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ฐธ๊ณ ๋กœ then ๋ฉ”์„œ๋“œ๋Š” ํ•ญ์ƒ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. then ๋ฉ”์„œ๋“œ์— ์ „๋‹ฌํ•œ ์ฝœ๋ฐฑ์ด ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์•„๋‹Œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์•”๋ฌต์ ์œผ๋กœ resolve ํ˜น์€ rejectํ•œ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•œ ํ›„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

const baseUrl = 'https://api.github.com/users';
const names = ['iliakan', 'remy', 'jeresig'];

// ์ฝ”๋“œ ํ‰๊ฐ€์‹œ then ํ›„์† ๋ฉ”์„œ๋“œ ์‹คํ–‰ -> then ๋ฉ”์„œ๋“œ์˜ ์ฝœ๋ฐฑ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ resolveํ•œ ํ”„๋กœ๋ฏธ์Šค ๋ฐ˜ํ™˜
// requests -> [Promise, Promise, Promise]
const requests = names.map((n) =>
  fetch(`${baseUrl}/${n}`).then((res) => res.json()),
);
// responses -> [{ id: 349336, name: 'Ilya Kantor', ... }, {...}, {...}]
const responses = await Promise.all(requests);

 

Promise.race


Promise.race ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ดํ–‰(fulfilled) ์ƒํƒœ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ , ๊ฐ€์žฅ ๋จผ์ € ์ฒ˜๋ฆฌ๋œ(fulfilled ํ˜น์€ rejected) ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

Promise.race([
  new Promise((resolve) => setTimeout(() => resolve(1), 5000)), // 3๋ฒˆ์งธ ์ดํ–‰
  new Promise((resolve) => setTimeout(() => resolve(2), 3000)), // 2๋ฒˆ์งธ ์ดํ–‰
  new Promise((resolve) => setTimeout(() => resolve(3), 1000)), // 1๋ฒˆ์งธ ์ดํ–‰
]).then(console.log); // 3 (๊ฐ€์žฅ ๋จผ์ € "์ฒ˜๋ฆฌ"๋œ ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ)

 

๊ฐ€์žฅ ๋จผ์ € ์ฒ˜๋ฆฌ๋œ ํ”„๋กœ๋ฏธ์Šค์˜ ๊ฒฐ๊ณผ๊ฐ€ ๊ฑฐ์ ˆ(rejected)๋ผ๋ฉด ๊ฑฐ์ ˆ๋œ ํ”„๋กœ๋ฏธ์Šค์˜ ์—๋Ÿฌ๋ฅผ ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

Promise.race([
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 1')), 5000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 2')), 3000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 3')), 1000)),
])
  .then(console.log) // ๊ฑด๋„ˆ๋œ€
  .catch(console.error); // Error: ์—๋Ÿฌ 3 (๊ฐ€์žฅ ๋จผ์ € "์ฒ˜๋ฆฌ"๋œ ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ)

 

์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” 2๋ฒˆ์งธ ํ”„๋กœ๋ฏธ์Šค๋ณด๋‹ค 3๋ฒˆ์งธ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๋จผ์ € ์ฒ˜๋ฆฌ(settled) ๋์œผ๋ฏ€๋กœ ์ฝ˜์†”์—” 3์„ ์ถœ๋ ฅํ•œ๋‹ค.

Promise.race([
  new Promise(resolve => setTimeout(() => resolve(1), 5000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 2')), 3000)),
  new Promise(resolve => setTimeout(() => resolve(3), 1000)), // 1๋ฒˆ์งธ ์ดํ–‰
])
  .then(console.log) // 3 (๊ฐ€์žฅ ๋จผ์ € "์ฒ˜๋ฆฌ"๋œ ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ)
  .catch(console.error); // ๊ฑด๋„ˆ๋œ€

 

Promise.allSettled


Promise.allSettled ๋ฉ”์„œ๋“œ๋Š” ์ธ์ž๋กœ ๋ฐ›์€ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๋ชจ๋‘ settled ์ƒํƒœ(fulfilled ํ˜น์€ rejected)๊ฐ€ ๋˜๋ฉด ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ฆ‰ rejected ์ƒํƒœ์™€ ์ƒ๊ด€์—†์ด ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค์˜ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ catch ๋ฉ”์„œ๋“œ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.

Promise.allSettled([
  new Promise((resolve) => setTimeout(() => resolve(1), 5000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 2')), 3000)),
  new Promise((resolve) => setTimeout(() => resolve(3), 1000)),
])
  .then(console.log) // [{…}, {…}, {…}] (์•„๋ž˜ ์ฃผ์„ ์ฐธ๊ณ )
  .catch(console.error); // ๊ฑด๋„ˆ๋œ€

/*
[
  { "status": "fulfilled", "value": 1 },
  { "status": "rejected", "reason": Error: ์—๋Ÿฌ 2 at <anonymous>:3:54 },
  { "status": "fulfilled", "value": 3 }
]
*/

 

  • fulfilled ์ƒํƒœ์ผ ๋•Œ ํ”„๋กœํผํ‹ฐ : ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ƒํƒœ status, ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ value
  • rejected ์ƒํƒœ์ผ ๋•Œ ํ”„๋กœํผํ‹ฐ : ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ƒํƒœ status, ์—๋Ÿฌ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” reason

 

๐Ÿ’ก Promise.all ๋ฉ”์„œ๋“œ๋Š” ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›์€ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ 1๊ฐœ๋ผ๋„ rejected ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ๋‚˜๋จธ์ง€ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ดํ–‰ ์ƒํƒœ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ์ข…๋ฃŒํ•œ๋‹ค. ์ด๋•Œ ์ดํ–‰๋œ ๋‹ค๋ฅธ ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ๋Š” ๋ฌด์‹œ๋˜๊ณ , ๊ฑฐ์ ˆ๋œ ํ”„๋กœ๋ฏธ์Šค์˜ ์—๋Ÿฌ๊ฐ€ Promise.all ์ „์ฒด์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋œ๋‹ค.

 

Promise.any


Promise.any๋Š” ๊ฑฐ์ ˆ๋œ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์žˆ์–ด๋„ ์ฒซ๋ฒˆ์งธ๋กœ ์ดํ–‰(fulfilled) ์ƒํƒœ๊ฐ€ ๋œ ํ”„๋กœ๋ฏธ์Šค์˜ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ฆ‰, ๊ฐ€์žฅ ๋จผ์ € ์ดํ–‰ ์ƒํƒœ๊ฐ€ ๋œ ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋งŒ์•ฝ โถ์ธ์ž๋กœ ๋ฐ›์€ ํ”„๋กœ๋ฏธ์Šค๋“ค์ด ๋ชจ๋‘ ๊ฑฐ์ ˆ ์ƒํƒœ๊ฐ€ ๋˜๊ฑฐ๋‚˜, โท๋นˆ ๋ฐฐ์—ด์„ ์ธ์ž๋กœ ๋ฐ›์•˜์„ ๋• ์—๋Ÿฌ(AggregateError)๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

์ดํ–‰ / ๊ฑฐ์ ˆ ์ƒํƒœ์˜ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ํ•จ๊ป˜ ์žˆ์„ ๋•Œ โ–ผ

Promise.any([
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 1'))), 1000),
  new Promise((resolve) => setTimeout(() => resolve(2), 3000)), // 1๋ฒˆ์งธ ์ดํ–‰
  new Promise((resolve) => setTimeout(() => resolve(3), 5000)),
])
  .then(console.log) // 2 (๊ฐ€์žฅ ๋จผ์ € "์ดํ–‰"๋œ ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ)
  .catch(console.error); // ๊ฑด๋„ˆ๋œ€

 

๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๊ฑฐ์ ˆ ์ƒํƒœ์ผ ๋•Œ โ–ผ

Promise.any([
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 1')), 5000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 2')), 3000)),
  new Promise((_, reject) => setTimeout(() => reject(new Error('์—๋Ÿฌ 3')), 1000)),
])
  .then(console.log) // ๊ฑด๋„ˆ๋œ€
  .catch(console.error); // AggregateError: All promises were rejected

 

๋นˆ ๋ฐฐ์—ด์„ ์ธ์ž๋กœ ๋ฐ›์•˜์„ ๋•Œ โ–ผ

Promise.any([]).then(console.log).catch(console.error);
// AggregateError: All promises were rejected

 

๐Ÿ’ก Promise.race vs Promise.any

  • Promise.race : ์ดํ–‰/๊ฑฐ์ ˆ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ๊ฐ€์žฅ ๋จผ์ € ์ฒ˜๋ฆฌ๋œ(settled) ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค
  • Promise.any : ๊ฑฐ์ ˆ๋œ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์žˆ์–ด๋„ ๋‹ค๋ฅธ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ดํ–‰ ์ƒํƒœ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค. ๋‹ค๋ฅธ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ์ดํ–‰ ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ํ•ด๋‹น ํ”„๋กœ๋ฏธ์Šค์˜ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

๋ ˆํผ๋Ÿฐ์Šค


 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”
๋ฐ˜์‘ํ˜•