๐Ÿฆœ Computer Language/JavaScript

[JavaScript] Promise | ์ฝœ๋ฐฑ์ง€์˜ฅ์„ ํƒˆ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•

 

๋™๊ธฐ & ๋น„๋™๊ธฐ ๊ธ€์—์„œ ๋“ฑ์žฅํ•œ ์ฝœ๋ฐฑ ์ง€์˜ฅ์„ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ Promise ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

Promise๋ž€?

: ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋น„๋™๊ธฐ๋ฅผ ๋•๋Š” ๊ฐ์ฒด์ด๋‹ค. ์ฝœ๋ฐฑ์„ ์ค„์ง€์–ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ด์ค€๋‹ค.

 

์šฐ์„ , ๋น„๋™๊ธฐ์ž‘์—…์ด ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ๋Œ€๊ธฐ(Pending): ๋น„๋™๊ธฐ ์ƒํƒœ๊ฐ€ ์ž‘์—… ์ค‘์ด๊ฑฐ๋‚˜ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ
  2. ์ดํ–‰(Fulfilled): ๋น„๋™๊ธฐ ์ƒํƒœ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ง„ํ–‰๋œ ์ƒํƒœ
  3. ๊ฑฐ๋ถ€(Rejected): ๋ฒ„๊ทธ, ๋˜๋Š” ์‹คํŒจํ•œ ์ƒํƒœ๋กœ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์ •์ƒ์ ์œผ๋กœ ์ง„ํ–‰๋˜์ง€ ์•Š์€ ์ƒํƒœ
  • resolve: ๋Œ€๊ธฐ => ์ดํ–‰
  • reject: ๋Œ€๊ธฐ => ๊ฑฐ๋ถ€
function isPositiveP(number) {
  const executor = (resolve, reject) => {
    setTimeout(() => {
      if (typeof number === "number") {
        resolve(number >= 0 ? "์–‘์ˆ˜" : "์Œ์ˆ˜");
      } else {
        reject("์ฃผ์–ด์ง„ ๊ฐ’์ด ์ˆซ์žํ˜• ๊ฐ’์ด ์•„๋‹™๋‹ˆ๋‹ค.");
      }
    }, 2000);
  };

  const asyncTask = new Promise(executor); // executor๋ฅผ ๋‹ด์€ Promise ๊ฐ์ฒด ์ƒ์„ฑ
  return asyncTask;
}


const res = isPositiveP(101);
res
  .then((res) => {
    console.log(`์ž‘์—… ์„ฑ๊ณต : ${res}`); // resolve ์ฝœ๋ฐฑํ•จ์ˆ˜์˜ ๊ฐ’ ์‹คํ–‰
  })
  .catch((err) => {
    console.log(`์ž‘์—… ์‹คํŒจ : ${err}`); // reject ์ฝœ๋ฐฑํ•จ์ˆ˜์˜ ๊ฐ’ ์‹คํ–‰
  });

executor๋ผ๋Š” ์ƒ์ˆ˜์—์„œ resolve, reject๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ setTimeout๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

resolve๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์ด ์„ฑ๊ณตํ–ˆ์„ ๋•Œ์˜ ์ฝœ๋ฐฑํ•จ์ˆ˜, reject๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์ด ์‹คํŒจํ–ˆ์„ ๋•Œ์˜ ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ executor()๊ฐ€ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์‹ค์ œ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
res๋Š” Promise ๊ฐ์ฒด๋ฅผ return ๋ฐ›๊ฒŒ ๋˜๋ฏ€๋กœ, ๋ฐ˜ํ™˜๋ฐ›์€ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  then๊ณผ catch๋ฅผ ํ†ตํ•ด resolve์™€ reject์˜ ๊ฒฐ๊ณผ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

Promise๋กœ ์ฝœ๋ฐฑ์ง€์˜ฅ์„ ํƒˆ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•

# Case 1. ์ฝœ๋ฐฑ ์ง€์˜ฅ

function taskA(a, b, cb) {
  setTimeout(() => {
    const res = a + b;
    cb(res);
  }, 3000);
}

function taskB(a, cb) {
  setTimeout(() => {
    const res = a * 2;
    cb(res);
  }, 1000);
}

function taskC(a, cb) {
  setTimeout(() => {
    const res = a * -1;
    cb(res);
  }, 2000);
}

taskA(3, 4, (a_res) => {
  console.log(`A TASK : ${a_res}`);
  taskB(a_res, (b_res) => {
    console.log(`B TASK : ${b_res}`);
    taskC(b_res, (c_res) => {
      console.log(`C TASK : ${c_res}`);
    });
  });
});

 

# Case 2. Promise๋ฅผ ์ด์šฉํ•œ ์ฝœ๋ฐฑ ์ง€์˜ฅ ํƒˆ์ถœ

function taskA(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000);
  });
}

function taskB(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}

function taskC(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * -1;
      resolve(res);
    }, 2000);
  });
}

taskA(5, 1)
  .then((a_res) => {
    console.log(`A RESULT : ${a_res}`);
    return taskB(a_res);
  })
  .then((b_res) => {
    console.log(`B RESULT : ${b_res}`);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log(`C RESULT : ${c_res}`);
  });

Promise ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๋ฉด, resolve ์ธ์ˆ˜๋ฅผ ํ†ตํ•ด callback ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ํ•ด๋‹น ์ž‘์—…์ด ๋ฐ˜๋ณต๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ then์„ ์‚ฌ์šฉํ•˜์—ฌ ์•„๋ž˜๋กœ ์—ฎ์–ด ๋‚˜๊ฐ€๋Š” ๊ฒƒ์€ then chaining์ด๋ผ๊ณ  ํ•œ๋‹ค.

  • then chaining์„ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๋Š” ์ฝœ๋ฐฑ ์ง€์˜ฅ ์ฝ”๋“œ๋ณด๋‹ค ์ง๊ด€์ ์ด๋ฉฐ, ๊ฐ€์‹œ์„ฑ์ด ์ข‹๋‹ค.
  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ chain ์ค‘ ํ•˜๋‚˜๋ผ๋„ reject๋˜๋ฉด ๋ฐ”๋กœ ๋งˆ์ง€๋ง‰์— ๋‹ฌ๋ฆฐ catch()๋กœ ๋‚ด๋ ค๊ฐ€์„œ (ํ•ด๋‹น ์ฝ”๋“œ์— reject ์ธ์ˆ˜์™€ ๋งˆ์ง€๋ง‰ ์ฝ”๋“œ์— .catch(~~)๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.) ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
    • ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋‚˜๋จธ์ง€ promise๊นŒ์ง€ ์ฐจ๋ก€์ฐจ๋ก€ ํ™•์ธํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • then์—์„œ ๋Š์€ ๋‹ค์Œ ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์ค‘๊ฐ„์— ์‚ฝ์ž…ํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.

    # Case3. ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์ค‘๊ฐ„์— ์‚ฝ์ž…ํ•˜์—ฌ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์˜ˆ์‹œ
  • function taskA(a, b) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const res = a + b;
          resolve(res);
        }, 3000);
      });
    }
    
    function taskB(a) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const res = a * 2;
          resolve(res);
        }, 1000);
      });
    }
    
    function taskC(a) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const res = a * -1;
          resolve(res);
        }, 2000);
      });
    }
    
    const PromiseResult2 = taskA(5, 1).then((a_res) => {
      console.log(`A RESULT : ${a_res}`);
      return taskB(a_res);
    });
    
    console.log("๋‹ค๋ฅธ์ž‘์—… 1");
    console.log("๋‹ค๋ฅธ์ž‘์—… 2");
    console.log("๋‹ค๋ฅธ์ž‘์—… 3");
    console.log("๋‹ค๋ฅธ์ž‘์—… 4");
    
    PromiseResult2
      .then((b_res) => {
        console.log(`B RESULT : ${b_res}`);
        return taskC(b_res);
      })
      .then((c_res) => {
        console.log(`C RESULT : ${c_res}`);
      });