Skip to content

Latest commit

ย 

History

History
537 lines (408 loc) ยท 23.2 KB

promise.md

File metadata and controls

537 lines (408 loc) ยท 23.2 KB

Promise

Promise(JS์˜ ๋น„๋™๊ธฐ ๋‹ด๋‹น ๊ฐ์ฒด)

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

ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด ์ƒ์„ฑ

const promise = new Promise(์‹คํ–‰ ํ•จ์ˆ˜);
  • ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ณ€์ˆ˜์ธ promise์— ์ €์žฅํ•จ
  • ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ์ธ์ˆ˜๋กœ ์‹คํ–‰ ํ•จ์ˆ˜(executor)๋ฅผ ์ „๋‹ฌํ•จ.
    • ์‹คํ–‰ ํ•จ์ˆ˜ : ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.
    • ์ด ํ•จ์ˆ˜๋Š” ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ๊ณผ ๋™์‹œ์— ์‹คํ–‰๋˜๋ฉฐ 2๊ฐœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณต๋ฐ›๋Š”๋‹ค.
const myPromise = new Promise((resolve, reject) => {
  // ๋น„๋™๊ธฐ ์ž‘์—… ์ˆ˜ํ–‰
  const data = fetch("์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์š”์ฒญํ•  URL");

  if (data) resolve(data); // ๋งŒ์ผ ์š”์ฒญ์ด ์„ฑ๊ณตํ•˜์—ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋ฉด
  else reject("Error"); // ๋งŒ์ผ ์š”์ฒญ์ด ์‹คํŒจํ•˜์—ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋ฉด
});
  • Promise ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด new ํ‚ค์›Œ๋“œ์™€ Promise ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ์ด๋•Œ Promise ์ƒ์„ฑ์ž ์•ˆ์— ๋‘๊ฐœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง„ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋„ฃ๊ฒŒ ๋˜๋Š”๋ฐ, ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ์ž‘์—…์ด ์„ฑ๊ณตํ–ˆ์„ ๋•Œ ์„ฑ๊ณต(resolve)์ž„์„ ์•Œ๋ ค์ฃผ๋Š” ๊ฐ์ฒด์ด๊ณ , ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ์ž‘์—…์ด ์‹คํŒจํ–ˆ์„ ๋•Œ ์‹คํŒจ(reject)์ž„์„ ์•Œ๋ ค์ฃผ๋Š” ์˜ค๋ฅ˜ ๊ฐ์ฒด์ด๋‹ค.

ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด ์ฒ˜๋ฆฌ

  • Promise ๊ฐ์ฒด๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋œ ์ดํ›„์— ๋‹ค์Œ ์ž‘์—…์„ ์—ฐ๊ฒฐ์‹œ์ผœ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž‘์—… ๊ฒฐ๊ณผ ๋”ฐ๋ผ.then()ย ๊ณผ.catch()ย ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹์„ ํ†ตํ•ด ์„ฑ๊ณต๊ณผ ์‹คํŒจ์— ๋Œ€ํ•œ ํ›„์† ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
myPromise
  .then((value) => {
    // ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ–ˆ์„ ๋•Œ ์‹คํ–‰๋  ์ฝ”๋“œ
    console.log("Data: ", value); // ์œ„์—์„œ return resolve(data)์˜ data๊ฐ’์ด ์ถœ๋ ฅ๋œ๋‹ค
  })
  .catch((error) => {
    // ์‹คํŒจํ–ˆ์„ ๋•Œ ์‹คํ–‰๋  ์ฝ”๋“œ
    console.error(error); // ์œ„์—์„œ return reject("Error")์˜ "Error"๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค
  })
  .finally(() => {
    // ์„ฑ๊ณตํ•˜๋“  ์‹คํŒจํ•˜๋“  ๋ฌด์กฐ๊ฑด ์‹คํ–‰๋  ์ฝ”๋“œ
  });
  • ์ฒ˜๋ฆฌ๋ฅผ ์„ฑ๊ณตํ•˜๋ฉด resolve(data)ย ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๊ณ , .then()ย ์œผ๋กœ ์ด์–ด์ ธthenย ๋ฉ”์„œ๋“œ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ ์„ฑ๊ณต์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.
  • ์ฒ˜๋ฆฌ๊ฐ€ ์‹คํŒจํ•˜๋ฉดย ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด ๋‚ด๋ถ€์—์„œย reject("Error")ย ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๊ณ ,ย .catch()ย ๋กœ ์ด์–ด์ ธ catchย ๋ฉ”์„œ๋“œ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ ์„ฑ๊ณต์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

ํ”„๋กœ๋ฏธ์Šค ํ•จ์ˆ˜ ๋“ฑ๋ก

  • ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ„๋„๋กœ ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค.
// ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ ์ƒ์„ฑ
function myPromise() {
  return new Promise((resolve, reject) => {
    if (/* ์„ฑ๊ณต ์กฐ๊ฑด */) {
      resolve(/* ๊ฒฐ๊ณผ ๊ฐ’ */);
    } else {
      reject(/* ์—๋Ÿฌ ๊ฐ’ */);
    }
  });
}

// ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ ์‚ฌ์šฉ
myPromise()
    .then((result) => {
      // ์„ฑ๊ณต ์‹œ ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜
    })
    .catch((error) => {
      // ์‹คํŒจ ์‹œ ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜
    });
  • ์œ„ ์˜ˆ์ œ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์„œ ํ”„๋กœ๋ฏธ์Šค ์ƒ์„ฑ์ž๋ฅผ returnํ•˜์—ฌ ์ƒ์„ฑ๋œ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ํ•จ์ˆ˜ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์–ป์–ด ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ฒ•์ด๋‹ค.
  • ์ด๋ ‡๊ฒŒ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ํ•จ์ˆ˜๋กœ ๋งŒ๋“œ๋Š” ์ด์œ ๋Š” ๋‹ค์Œ 3๊ฐ€์ง€ ์ •๋„๊ฐ€ ์žˆ๋‹ค.
    • ์žฌ์‚ฌ์šฉ์„ฑ : ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค๋ฉด ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ, ๋ฐ˜๋ณต๋˜๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ฐ€๋…์„ฑ : ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค๋ฉด ์ฝ”๋“œ์˜ ๊ตฌ์กฐ๊ฐ€ ๋ช…ํ™•ํ•ด์ ธ, ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ •์˜์™€ ์‚ฌ์šฉ์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.
    • ํ™•์žฅ์„ฑ : ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค๋ฉด ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ๋™์ ์œผ๋กœ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋“ค์„ ์—ฐ๊ฒฐํ•˜์—ฌ ๋ณต์žกํ•œ ๋น„๋™๊ธฐ ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋Ÿฌํ•œ ์ ์œผ๋กœ ์ธํ•ด ์‹ค๋ฌด์—์„œ๋Š” ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ผ์ด ์žˆ๋‹ค๋ฉด ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ์„œ ์‚ฌ์šฉํ•œ๋‹ค. js์˜ fetch() ๋ฉ”์„œ๋“œ๋Š” fetch() ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด resolve()ํ•˜์—ฌ .then()์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.
// GET ์š”์ฒญ ์˜ˆ์‹œ
fetch("https://jsonplaceholder.typicode.com/posts/1")
  .then((response) => response.json()) // ์‘๋‹ต ๊ฐ์ฒด์—์„œ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•œ๋‹ค.
  .then((data) => console.log(data)); // JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ˜์†”์— ์ถœ๋ ฅํ•œ๋‹ค.

ํ”„๋กœ๋ฏธ์Šค 3๊ฐ€์ง€ ์ƒํƒœ

Promise ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ง„ํ–‰ ๋‹จ๊ณ„์— ๋”ฐ๋ผ 3๊ฐ€์ง€ ์ƒํƒœ๋กœ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ•จ

  • Pending(๋Œ€๊ธฐ) : ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์ƒํƒœ (์ฒ˜๋ฆฌ ์ง„ํ–‰์ค‘)
  • Fulfilled(์ดํ–‰) : ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋œ ์ƒํƒœ
  • Eejected(๊ฑฐ๋ถ€) : ์ฒ˜๋ฆฌ๊ฐ€ ์‹คํŒจ๋กœ ๋๋‚œ ์ƒํƒœ

image

Pending ์ƒํƒœ

  • ๋Œ€๊ธฐ(Pending) ์ƒํƒœ๋ž€, ๋ง ๊ทธ๋Œ€๋กœ ์•„์ง ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋กœ์ง์ด ์™„๋ฃŒ ๋˜์ง€ ์•Š์€ ์ƒํƒœ์ด๋‹ค
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("์ฒ˜๋ฆฌ ์™„๋ฃŒ");
  }, 5000);
});
console.log(promise); // Pending (๋Œ€๊ธฐ) ์ƒํƒœ

image

Fulfilled ์ƒํƒœ

  • ์ดํ–‰(fulfilled) ์ƒํƒœ๋ž€, ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋กœ์ง์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ ๋ฌ๋‹ค๋Š” ๊ฒƒ์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์ƒํƒœ๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.
  • ์œ„์˜ ํ”„๋กœ๋ฏธ์Šค ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  5์ดˆ ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฌ๋‹ค๊ฐ€ ๋‹ค์‹œ ์ฝ˜์†”์„ ์ถœ๋ ฅํ•˜๋ฉด. ์•„๋ž˜์™€ ๊ฐ™์ด ์ดํ–‰(fulfilled) ์ƒํƒœ๋กœ ๋ณ€ํ•˜๊ฒŒ ๋œ๋‹ค.

image

  • 5์ดˆ๊ฐ€ ์ง€๋‚˜ resolve() ์ˆ˜ํ–‰๋˜๋ฉด์„œ ํ”„๋กœ๋ฏธ์Šค ์„ฑ๊ณต์„ ์•Œ๋ฆฌ๋Š” ๊ฐœ์ฒด๋ฅผ ํ˜ธ์ถœํ•˜์˜€์œผ๋‹ˆ ์ดํ–‰ ์ƒํƒœ๋กœ ๋ณ€ํ•œ ๊ฒƒ์ด๋‹ค.

image

  • ์ดํ–‰ ์ƒํƒœ๋กœ ๋ณ€ํ•œ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋Š” ๋ฐ”๋กœ ์ฒด์ด๋‹๋œ .then() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
promise.then((data) => {
  console.log("ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ดํ–‰ ์ƒํƒœ๊ฐ€ ๋˜๋ฉด์„œ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜ํ–‰");
});

Rejected ์ƒํƒœ

  • reject()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๊ฐ€ ์‹คํŒจ(rejected) ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

image

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("์ฒ˜๋ฆฌ ์‹คํŒจ");
  }, 5000);
});

image

  • ์‹คํŒจ ์ƒํƒœ๋กœ ๋ณ€ํ•œ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋Š” ๋ฐ”๋กœ ์ฒด์ด๋‹๋œ.catch()ย ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ฒ˜๋ฆฌ ์‹คํŒจ์— ๋Œ€ํ•œ ํ–‰๋™์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค.
promise.catch((error) => {
  console.log(error);
  console.log("์‹คํŒจ์— ๋Œ€ํ•œ ํ›„์† ์กฐ์น˜...");
});

์œ ํŠœ๋ธŒ ์˜์ƒ ์‹œ์ฒญํ•˜๋Š” ์ƒํ™ฉ Promise ๊ฐ์ฒด์˜ 3๊ฐ€์ง€ ์˜ˆ์‹œ)

image

  • ์‹œ์ฒญ์ž๊ฐ€ ํŠน์ • ์˜์ƒ์„ ์‹œ์ฒญํ•˜๊ธฐ ์œ„ํ•ด ํด๋ฆญํ•˜๋ฉด ํ•ด๋‹น ์˜์ƒ์„ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ์˜์ƒ ๋กœ๋”ฉ ์ž‘์—…์€ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋™์ž‘ํ•จ
    • ์ฆ‰, ์˜์ƒ์ด ๋กœ๋”ฉ๋˜๊ธฐ๊นŒ์ง€ ์‚ฌ์šฉ์ž๋Š” ๋‹ค๋ฅธ ์˜์ƒ์„ ํƒ์ƒ‰ํ•˜๊ฑฐ๋‚˜ ๋Œ“๊ธ€์„ ๋‹ค๋Š” ๋“ฑ์˜ ํ–‰๋™์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์˜์ƒ ๋กœ๋”ฉ ๊ณผ์ •์—์„œ ์˜์ƒ์ด ๋กœ๋”ฉ ์ค‘์ธ ์ƒํƒœ๋ฅผ โ€˜๋Œ€๊ธฐ ์ƒํƒœโ€™๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ •์ƒ์ ์œผ๋กœ ์˜์ƒ์ด ๋กœ๋”ฉ๋˜์—ˆ๋‹ค๋ฉด ์ด๋ฅผ โ€˜ํ•ด๊ฒฐโ€™์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ์ƒํƒœ๋ฅผ โ€˜์„ฑ๊ณต ์ƒํƒœโ€™๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์˜์ƒ์ด ๋ชจ์ข…์˜ ์ด์œ ๋กœ ๋กœ๋”ฉ๋˜์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ์ด๋ฅผ โ€˜๊ฑฐ๋ถ€โ€™๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ์ƒํƒœ๋Š” โ€˜์‹คํŒจ ์ƒํƒœโ€™๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Œ

ํ”„๋กœ๋ฏธ์Šค ํ•ธ๋“ค๋Ÿฌ

  • ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด, ์„ฑ๊ณต/ ์‹คํŒจ ๊ฒฐ๊ณผ๋ฅผ .then / .catch / .finally ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ๋ฐ›์•„ ๋‹ค์Œ ํ›„์† ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ”„๋กœ๋ฏธ์Šค ํ•ธ๋“ค๋Ÿฌ๋Š” ํ”„๋กœ๋ฏธ์Šค์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ์‹คํ–‰๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.
    • .then() : ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ดํ–‰(fulfilled)๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•˜๊ณ , ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜
    • .catch() : ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๊ฑฐ๋ถ€(rejected)๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•˜๊ณ , ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜
    • .finally() : ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ดํ–‰๋˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€๋  ๋•Œ ์ƒ๊ด€์—†์ด ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•˜๊ณ , ์ƒˆ๋กœ์šด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜
  • ๋งˆ์น˜ try - catch - finally ๊ตฌ์กฐ์™€ ์œ ์‚ฌํ•˜๋‹ค.

ํ”„๋กœ๋ฏธ์Šค ์ฒด์ด๋‹

  • ํ”„๋กœ๋ฏธ์Šค ์ฒด์ด๋‹์ด๋ž€ ํ”„๋กœ๋ฏธ์Šค ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฐ๋‹ฌ์•„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์ด๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ๋‹ค.
  • ํ”„๋กœ๋ฏธ์Šค๋Š” then, catch, finally ํ›„์† ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ฝœ๋ฐฑ ํ—ฌ์„ ํ•ด๊ฒฐํ•œ๋‹ค.
function doSomething() {
  return new Promise((resolve, reject) => {
      resolve(100)
  });
}

doSomething()
    .then((value1) => {
        const data1 = value1 + 50;
        return data1
    })
    .then((value2) => {
        const data2 = value2 + 50;
        return data2
    })
    .then((value3) => {
        const data3 = value3 + 50;
        return data3
    })
    .then((value4) => {
        console.log(value4); // 250 ์ถœ๋ ฅ
    })

image

  • ์œ„ doSomething ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , then ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ดํ–‰ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ์ •์ด๋‹ค. ๊ฐ ์ดํ–‰ ํ•ธ๋“ค๋Ÿฌ๋Š” ์ด์ „ ํ”„๋กœ๋ฏธ์Šค์˜ ๊ฐ’์— 50์„ ๋”ํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋งˆ์ง€๋ง‰ ์ดํ–‰ ํ•ธ๋“ค๋Ÿฌ๋Š” ์ตœ์ข…๊ฐ’์„ ์ฝ˜์†”์— ์ถœ๋ ฅํ•œ๋‹ค.
  • ์ด๋Ÿฌํ•œ ์ฒด์ด๋‹์ด ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” then ํ•ธ๋“ค๋Ÿฌ์—์„œ ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๋ฉด, ๊ทธ ๋ฐ˜ํ™˜๊ฐ’์€ ์ž๋™์œผ๋กœ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋กœ ๊ฐ์‹ธ์ ธ ๋ฐ˜ํ™˜๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ then ํ•ธ๋“ค๋Ÿฌ์—์„œ ๋ฐ˜ํ™˜๋œ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ด์˜ ํ”„๋กœ๋ฏธ์Šค ์ƒํƒœ์˜ ํ๋ฆ„๋„๋ฅผ ํ‘œํ˜„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

image


function doSomething(arg) {
  return new Promise((resolve, reject) => {
      resolve(arg)
  });
}

doSomething('100A')
    .then((value1) => {
        const data1 = value1 + 50; // ์ˆซ์ž์— ๋ฌธ์ž๋ฅผ ์—ฐ์‚ฐ

        if (isNaN(data1))
            throw new Error('๊ฐ’์ด ๋„˜๋ฒ„๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค')

        return data1
    })
    .then((value2) => {
        const data2 = value2 + 50;
        return data2
    })
    .catch((err) => {
        console.error(err);
    }

image

  • ๋งŒ์ผ ์—ฐ๊ฒฐ๋œ ์ดํ–‰ ํ•ธ๋“ค๋Ÿฌ์—์„œ ์ค‘๊ฐ„์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ์ฒ˜๋ฆฌ๋ฅผ ํ–‰ํ•œ๋‹ค๋ฉด ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•จ์œผ๋กœ์จ catch ํ•ธ๋“ค๋Ÿฌ์— ์ ํ”„ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
new Promise((resolve, reject) => {
  throw new Error("์—๋Ÿฌ ๋ฐœ์ƒ!");
})
    .catch(function(error) {
      console.log("์—๋Ÿฌ๊ฐ€ ์ž˜ ์ฒ˜๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰์ด ์ด์–ด์ง‘๋‹ˆ๋‹ค.");
    })
    .then(() => {
        console.log("๋‹ค์Œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.")
    })
    .then(() => {
        console.log("๋‹ค์Œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋˜ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.")
    });

image

  • catch ํ•ธ๋“ค๋Ÿฌ ๋‹ค์Œ์œผ๋กœ then ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ด์–ด์„œ ์ฒด์ด๋‹ ๋˜์–ด ์žˆ๋‹ค๋ฉด, ์—๋Ÿฌ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๊ณ  ๊ฐ€๊นŒ์šด then ํ•ธ๋“ค๋Ÿฌ๋กœ ์ œ์–ด ํ๋ฆ„์ด ๋„˜์–ด๊ฐ€ ์‹คํ–‰์ด ์ด์–ด์ง€๊ฒŒ ๋œ๋‹ค.

ํ”„๋กœ๋ฏธ์Šค ์ •์  ๋ฉ”์„œ๋“œ

  • ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์™ธ์—๋„ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ •์  ๋ฉ”์„œ๋“œ(static method)๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ •์  ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™” & ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ๋ณด๋‹ค ํšจ์œจ์ ์ด๊ณ  ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

Promise.resolve()

// ํ”„๋กœ๋ฏธ์Šค ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
function getPromiseNumber() {
  return new Promise((resolve, reject) => {
    const num = Math.floor(Math.random() * 10); // 0 ~ 9 ์‚ฌ์ด์˜ ์ •์ˆ˜
    resolve(num); // ํ”„๋กœ๋ฏธ์Šค ์ดํ–‰
  });
}

// Promise {<fulfilled>: 3}
  • Promise.resolve() ์ •์  ๋ฉ”์„œ๋“œ๋กœ ํ•œ๋ฒˆ์— ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ํŽธ์˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์ค€๋‹ค.
  • ํ”„๋กœ๋ฏธ์Šค ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด์™€ ์ „ํ˜€ ์—ฐ๊ด€์—†๋Š” ํ•จ์ˆ˜ ๋‚ด์—์„œ ํ•„์š”์— ๋”ฐ๋ผ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์‘์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š” ํ•จ์ˆ˜์—์„œ๋„ ํ”„๋กœ๋ฏธ์Šค์˜ ์žฅ์ ์„ ํ™œ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ์œ ์šฉํ•˜๋‹ค.
// ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด์™€ ์ „ํ˜€ ์—ฐ๊ด€์—†๋Š” ํ•จ์ˆ˜
function getRandomNumber() {
  const num = Math.floor(Math.random() * 10); // 0 ~ 9 ์‚ฌ์ด์˜ ์ •์ˆ˜
  return num;
}

// Promise.resolve() ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
function getPromiseNumber() {
  const num = getRandomNumber(); // ์ผ๋ฐ˜ ๊ฐ’
  return Promise.resolve(num); // ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด
}

// ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด์˜ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜
getPromiseNumber()
  .then((value) => {
    console.log(`๋žœ๋ค ์ˆซ์ž: ${value}`);
  })
  .catch((error) => {
    console.error(error);
  });

Promise.reject()

  • ์ฃผ์–ด์ง„ ์‚ฌ์œ ๋กœ ๊ฑฐ๋ถ€ํ•˜๋Š” Promise ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค
// ์ฃผ์–ด์ง„ ์‚ฌ์œ ๋กœ ๊ฑฐ๋ถ€๋˜๋Š” ํ”„๋กœ๋ฏธ์Šค ์ƒ์„ฑ
const p = Promise.reject(new Error("error"));

// ๊ฑฐ๋ถ€ ์‚ฌ์œ ๋ฅผ ์ถœ๋ ฅ
p.catch((error) => console.error(error)); // Error: error

Promise.all()

  • ๋ฐฐ์—ด, Map, Set์— ํฌํ•จ๋œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ”„๋กœ๋ฏธ์Šค ์š”์†Œ๋“ค์„ ํ•œ๊บผ๋ฒˆ์— ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ๋•Œ ์œ ์šฉํ•œ ํ”„๋กœ๋ฏธ์Šค ์ •์  ๋ฉ”์†Œ๋“œ์ด๋‹ค.
  • ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์ดํ–‰(fulfilled) ๋ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์„œ, ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ๊ทธ๋•Œ then ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰ํ•˜๋Š” ํ˜•ํƒœ์ด๋‹ค. ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ์‚ฌ์šฉ ์˜ˆ์‹œ๋กœ ์—ฌ๋Ÿฌ ๊ฐœ์˜ API ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ๋ชจ๋“  ์‘๋‹ต์„ ๋ฐ›์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
// 1. ์„œ๋ฒ„ ์š”์ฒญ API ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด ์ƒ์„ฑ (fetch)
const api_1 = fetch("https://jsonplaceholder.typicode.com/users");
const api_2 = fetch("https://jsonplaceholder.typicode.com/users");
const api_3 = fetch("https://jsonplaceholder.typicode.com/users");

// 2. ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋“ค์„ ๋ฌถ์–ด ๋ฐฐ์—ด๋กœ ๊ตฌ์„ฑ
const promises = [api_1, api_2, api_3];

// 3. Promise.all() ๋ฉ”์„œ๋“œ ์ธ์ž๋กœ ํ”„๋กœ๋ฏธ์Šค ๋ฐฐ์—ด์„ ๋„ฃ์–ด, ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ดํ–‰๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ณ , ๊ฒฐ๊ณผ๊ฐ’์„ ์ถœ๋ ฅ
Promise.all(promises)
  .then((results) => {
    // results๋Š” ์ดํ–‰๋œ ํ”„๋กœ๋ฏธ์Šค๋“ค์˜ ๊ฐ’๋“ค์„ ๋‹ด์€ ๋ฐฐ์—ด.
    // results์˜ ์ˆœ์„œ๋Š” promises์˜ ์ˆœ์„œ์™€ ์ผ์น˜.
    console.log(results); // [users1, users2, users3]
  })
  .catch((error) => {
    // ์–ด๋Š ํ•˜๋‚˜๋ผ๋„ ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๊ฑฐ๋ถ€๋˜๋ฉด ์˜ค๋ฅ˜๋ฅผ ์ถœ๋ ฅ
    console.error(error);
  });

Promise.allSettled()

  • Promise.all() ๋ฉ”์„œ๋“œ์˜ ์ƒ์œ„ ๋ฒ„์ „์œผ๋กœ, ์ฃผ์–ด์ง„ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋ฉด ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค ๊ฐ๊ฐ์˜ ์ƒํƒœ์™€ ๊ฐ’ (๋˜๋Š” ๊ฑฐ๋ถ€ ์‚ฌ์œ )์„ ๋ชจ์•„๋†“์€ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
// 1์ดˆ ํ›„์— 1์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ”„๋กœ๋ฏธ์Šค
const p1 = new Promise((resolve) => setTimeout(() => resolve(1), 1000));

// 2์ดˆ ํ›„์— ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ํ”„๋กœ๋ฏธ์Šค
const p2 = new Promise((resolve, reject) =>
  setTimeout(() => reject(new Error("error")), 2000)
);

// 3์ดˆ ํ›„์— 3์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ”„๋กœ๋ฏธ์Šค
const p3 = new Promise((resolve) => setTimeout(() => resolve(3), 3000));

// ์„ธ ๊ฐœ์˜ ํ”„๋กœ๋ฏธ์Šค์˜ ์ƒํƒœ์™€ ๊ฐ’ ๋˜๋Š” ์‚ฌ์œ ๋ฅผ ์ถœ๋ ฅ
Promise.allSettled([p1, p2, p3]).then((result) => console.log(result));

image

Promise.any()

  • Promise.all()ย ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜๋Œ€ ๋ฒ„์ „์œผ๋กœ, Promise.all()์ดย ์ฃผ์–ด์ง„ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๋ชจ๋‘ ์™„๋ฃŒํ•ด์•ผ๋งŒ ๊ฒฐ๊ณผ๋ฅผ ๋„์ถœํ•œ๋‹ค๋ฉด,
  • Promise.any()๋Š” ์ฃผ์–ด์ง„ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค ์ค‘ **ํ•˜๋‚˜๋ผ๋„ ์™„๋ฃŒ(์ดํ–‰)**๋˜๋ฉด ๋ฐ”๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ •์  ๋ฉ”์„œ๋“œ์ด๋‹ค.
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("promise1 failed");
  }, 3000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("promise2 succeeded");
  }, 2000);
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("promise3 failed");
  }, 1000);
});

// promise1, promise2, promise3์€ ๊ฐ๊ฐ 3์ดˆ, 2์ดˆ, 1์ดˆ ํ›„์— ๊ฑฐ๋ถ€๋˜๊ฑฐ๋‚˜ ์ดํ–‰
Promise.any([promise1, promise2, promise3])
  .then((value) => {
    console.log(value); // "promise2 succeeded"
  })
  .catch((error) => {
    console.error(error);
  });

// ๊ฒฐ๊ด๊ฐ’ :
// promise2 succeeded
  • ์œ„ ์ฝ”๋“œ๋Š” Promise.any() ๋ฉ”์„œ๋“œ์˜ ๊ฒฐ๊ณผ๋กœ promise2์˜ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ๋จผ์ € ๋„์ถœ๋จ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ฒซ๋ฒˆ์งธ๋กœ ์ดํ–‰(fulfilled) ๋œ ํ”„๋กœ๋ฏธ์Šค๋งŒ์„ ์ทจ๊ธ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜๋จธ์ง€ promise1๊ณผ promise3์˜ ๊ฑฐ๋ถ€(rejected)๋Š” ๋ฌด์‹œ๋˜๊ฒŒ ๋œ๋‹ค.
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("promise1 failed");
  }, 3000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("promise2 succeeded");
  }, 2000);
});

const promise4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("promise4 failed");
  }, 4000);
});

Promise.any([promise1, promise3, promise4])
  .then((value) => {
    console.log(value);
  })
  .catch((error) => {
    console.error(error); // AggregateError: All promises were rejected
    console.error(error.errors); // ["promise3 failed", "promise1 failed", "promise4 failed"]
  });
  • ๋งŒ์•ฝ ์š”์ฒญ๋œ ๋ชจ๋“  ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๊ฑฐ๋ถ€(rejected)๋˜๋ฉด, AggregateError ๊ฐ์ฒด๋ฅผ ์‚ฌ์œ ๋กœ ํ•˜๋Š” ๊ฑฐ๋ถ€ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

Promise.race()

new Promise((resolve, reject) => {
  throw new Error("์—๋Ÿฌ ๋ฐœ์ƒ!");
})
  .catch(function (error) {
    console.log("์—๋Ÿฌ๊ฐ€ ์ž˜ ์ฒ˜๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰์ด ์ด์–ด์ง‘๋‹ˆ๋‹ค.");
  })
  .then(() => {
    console.log("๋‹ค์Œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.");
  })
  .then(() => {
    console.log("๋‹ค์Œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋˜ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.");
  });
  • Promise.race()๋Š” Promise.any() ์™€ ๊ฐ™์ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ๋ฏธ์Šค ์ค‘ ๊ฐ€์žฅ ๋จผ์ € ์ฒ˜๋ฆฌ๋œ ํ”„๋กœ๋ฏธ์Šค์˜ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ฐจ์ด์ ์ด ์กด์žฌํ•œ๋‹ค.
  • Promise.any()๋Š” ๊ฐ€์žฅ ๋จผ์ € fulfilled(์ดํ–‰) ์ƒํƒœ๊ฐ€ ๋œ ํ”„๋กœ๋ฏธ์Šค๋งŒ์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜, ํ˜น์€ ์ „๋ถ€ rejected(์‹คํŒจ) ์ƒํƒœ๊ฐ€ ๋œ ํ”„๋กœ๋ฏธ์Šค(AggregateError)๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ๋ฐ˜๋ฉด Promise.race()๋Š” fulfilled(์ดํ–‰), rejected(์‹คํŒจ) ์—ฌ๋ถ€ ์ƒ๊ด€์—†์ด ๋ฌด์กฐ๊ฑด ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚œ ํ”„๋กœ๋ฏธ์Šค ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋‹ค.
๐Ÿ’ก ๋งˆ์น˜ ํ”„๋กœ๋ฏธ์Šค ์ฐธ๊ฐ€์ž๋“ค์ด ๋ ˆ์ด์‹ฑ(race) ๊ฒฝ์ฃผ๋ฅผ ํ•˜๋Š”๊ฒƒ์„ ๋– ์˜ฌ๋ฆฌ๋ฉด ๋œ๋‹ค.

Promise.any ์˜ˆ์‹œ)

image

Promise.race ์˜ˆ์‹œ)

image

Promise ๋‚ด๋ถ€ ๋™์ž‘ ๊ณผ์ •

  • Callback Queue์˜ ์ข…๋ฅ˜์—๋Š” (Macro)Task Queue, MicroTask Queue 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค
    • ๊ทธ์ค‘ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Promise ๊ฐ์ฒด์˜ ์ฝœ๋ฐฑ์ด ์Œ“์ด๋Š” ๊ณณ์ด ๋ฐ”๋กœ MicroTask Queue์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  MicroTask Queue๋Š” ๊ทธ ์–ด๋–ค ๊ณณ๋ณด๋‹ค ๊ฐ€์žฅ ๋จผ์ € ์šฐ์„ ์œผ๋กœ ์ฝœ๋ฐฑ์ด ์ฒ˜๋ฆฌ๋˜๊ฒŒ ๋œ๋‹ค.

image

console.log('Start!');

setTimeout(() => {
	console.log('Timeout!');
}, 0);

Promise.resolve('Promise!').then(res => console.log(res));

console.log('End!');
  1. Call Stack์—console.log('Start!') ์ฝ”๋“œ ๋ถ€๋ถ„์ด ์Œ“์ธ ๋’ค ์‹คํ–‰ ๋˜์–ด ์ฝ˜์†”์ฐฝ์— "Start!"ย ๊ฐ€ ์ถœ๋ ฅ
  2. setTimeout ์ฝ”๋“œ๊ฐ€ ์ฝœ ์Šคํƒ์— ์ ์žฌ๋˜๊ณ  ์‹คํ–‰๋˜๋ฉด, ๊ทธ ์•ˆ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ด๋ฒคํŠธ ๋ฃจํ”„์— ์˜ํ•ด Web API๋กœ ์˜ฎ๊ฒจ์ง€๊ณ  ํƒ€์ด๋จธ๊ฐ€ ์ž‘๋™ํ•˜๊ฒŒ ๋œ๋‹ค. (0์ดˆ๋ผ์„œ ์‚ฌ์‹ค์ƒ ๋ฐ”๋กœ ํƒ€์ด๋จธ๋Š” ์ข…๋ฃŒ๋œ๋‹ค)
  3. ํƒ€์ด๋จธ๊ฐ€ ์ข…๋ฃŒ๋จ์— ๋”ฐ๋ผsetTimeoutย ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š”ย MacroTask Queue์— ์ด๋ฒคํŠธ ๋ฃจํ”„์— ์˜ํ•ด ์ ์žฌ๋˜๊ฒŒ ๋œ๋‹ค.
  4. Promise ์ฝ”๋“œ๊ฐ€ ์ฝœ์Šคํƒ์— ์ ์žฌ ๋˜์–ด ์‹คํ–‰๋˜๊ณ then ํ•ธ๋“ค๋Ÿฌ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ด๋ฒคํŠธ ๋ฃจํ”„์— ์˜ํ•ด MicroTaskย Queue์— ์ ์žฌ๋˜๊ฒŒ ๋œ๋‹ค.
  5. console.log('End!') ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ณ  "End!" ํ…์ŠคํŠธ๊ฐ€ ์ฝ˜์†”์ฐฝ์— ์ถœ๋ ฅ๋œ๋‹ค.
  6. ๋ชจ๋“  ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰์ด๋˜์–ด ๋”์ด์ƒ Call Stack์—” ์‹คํ–‰ํ•  ์Šคํƒ์ด ์—†์–ด ๋น„์›Œ์ง€๊ฒŒ ๋œ๋‹ค.
  7. ๊ทธ๋Ÿฌ๋ฉด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ด๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ, Callback Queue์— ๋‚จ์•„์žˆ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋“ค์„ ๋นผ์™€ Call Stack์— ์ ์žฌํ•˜๊ฒŒ ๋œ๋‹ค
  8. ์ด๋•Œ 2์ข…๋ฅ˜์˜ Queue ์ค‘ MicroTask Queue์— ๋‚จ์•„์žˆ๋Š” ์ฝœ๋ฐฑ์ด ์šฐ์„ ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค. (๋งŒ์ผ ์ฝŸ๊ฐœ์ด ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ „๋ถ€ ์ฒ˜๋ฆฌ๋œ๋‹ค)
  9. MicroTask Queue๊ฐ€ ๋น„์–ด์ง€๋ฉด, ์ด์ œ ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” MacroTask Queue์— ์žˆ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ Call Stack์— ์ ์žฌํ•ด ์‹คํ–‰๋˜๊ฒŒ ๋œ๋‹ค.

image

ํ”„๋กœ๋ฏธ์Šค ์ •์  ๋ฉ”์„œ๋“œ

  • Promise.resolve() : ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ƒํƒœ๋ฅผ ์„ฑ๊ณต์œผ๋กœ ๋ฐ”๊พธ๋Š” ํ•จ์ˆ˜

  • Promise.reject() : ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ƒํƒœ๋ฅผ ์‹คํŒจ๋กœ ๋ฐ”๊พธ๋Š” ํ•จ์ˆ˜

    ๐Ÿ“ข ์•ž์„œ ์‚ดํŽด ๋ณด์•˜๋“ฏ์ด ํ”„๋กœ๋ฏธ์Šค๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ƒํƒœ๋ฅผ ๋Œ€๊ธฐ(Pending), ์„ฑ๊ณต(Fulfilled), ์‹คํŒจ(Rejected)๋กœ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ•จ. ์‹คํ–‰ ํ•จ์ˆ˜๊ฐ€ ์ œ๊ณต๋ฐ›๋Š” 2๊ฐœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋Œ€๊ธฐ ์ƒํƒœ์˜ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์„ฑ๊ณต ๋˜๋Š” ์‹คํŒจ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ์—ญํ• ์„ ํ•จ

์‹คํ–‰ ํ•จ์ˆ˜์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ œ๊ณต๋œ resolve๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ž‘์—… ์ƒํƒœ๋ฅผ ์„ฑ๊ณต ์ƒํƒœ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ์˜ˆ์‹œ)

const promise = new Promise(function (resolve, reject) {
  setTimeout(() => {
    resolve("์„ฑ๊ณต");
  }, 500);
});
  • ์œ„ ์˜ˆ์ œ๋Š” 0.5์ดˆ ๊ธฐ๋‹ค๋ฆฐ ํ›„ resolve๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ๊ฐ’ โ€œ์„ฑ๊ณตโ€์€ ๋น„๋™๊ธฐ ์ž‘์—…์˜ ๊ฒฐ๊ด๊ฐ’์ด ๋œ๋‹ค.
  • ์ด ๊ฒฐ๊ด๊ฐ’์„ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์•„๋‹Œ ๊ณณ์—์„œ ์ด์šฉํ•˜๋ ค๋ฉด ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด์˜ then ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค. then ๋ฉ”์„œ๋“œ๋Š” ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์„ฑ๊ณตํ–ˆ์„ ๋•Œ ์‹คํ–‰ํ•œ๋‹ค.

์ฐธ๊ณ 

๋ชจ๋˜ js ๋”ฅ๋‹ค์ด๋ธŒ https://inpa.tistory.com/entry/๐Ÿ”„-์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ-์ด๋ฒคํŠธ-๋ฃจํ”„-๊ตฌ์กฐ-๋™์ž‘-์›๋ฆฌ#promise๋‚ด๋ถ€๋™์ž‘_๊ณผ์ •

ํ•œ์ž… ํฌ๊ธฐ ๋ฆฌ์•กํŠธ