๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“‹Technical interview(Front)

Promise

by ๋…น์ฐจ๋ง›๊ฐœ๊ตฌ๋ฆฌ 2022. 11. 16.

Promise๊ฐ€ ๋ญ”๊ฐ€์š”?

ํ”„๋กœ๋ฏธ์Šค๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด์ด๋‹ค.

์—ฌ๊ธฐ์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ž€ ‘ํŠน์ • ์ฝ”๋“œ์˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ 

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์ˆ˜ํ–‰ํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํŠน์„ฑ’์„ ์˜๋ฏธํ•œ๋‹ค.

 

์ผ๋ฐ˜์ ์œผ๋กœ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌํ˜„ํ•  ๋•Œ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ  ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด API๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ,
API๊ฐ€ ์‹คํ–‰๋˜๋ฉด ์„œ๋ฒ„์—๋‹ค๊ฐ€ ๋ฐ์ดํ„ฐ ๋ณด๋‚ด๋‹ฌ๋ผ๋Š” ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ ,
๋ณด๋‚ด์˜จ ๋ฐ์ดํ„ฐ์˜ ๋ฐ˜ํ™˜๊ฐ’์ด๋‚˜, ์—๋Ÿฌ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.


promise๋ฅผ ์‚ฌ์šฉํ•œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ

function async() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {   // setTimeout <- api ํ†ต์‹  ๊ฐ€์ •ํ•˜์— 1์ดˆ๋’ค์— ์‹คํ–‰๋˜๋Š”๊ฑธ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•จ
      resolve("i'm here!!");
    }, 1000);
  })
}

async().then(res => {
  console.log(res);
});

promise๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด resolve๋Š” ์„ฑ๊ณตํ–ˆ์„ ๋•Œ, reject๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ ํ–ˆ์„ ๋•Œ

์ฒซ ๋ฒˆ์งธ ์ธ์ž( ์œ„์˜ ์˜ˆ์‹œ์—์„œ๋Š” res )๋กœ ์–ด๋– ํ•œ ๊ฐ’์„ ๋„˜๊ธธ ์ˆ˜ ์žˆ๋‹ค.

resolve๋Š” .then์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ, reject๋Š” .catch์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋“ค์–ด๊ฐ„๋‹ค.

 

์œ„ ์˜ˆ์‹œ์—์„œ async ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด 1์ดˆ ํ›„ ์ฒซ ๋ฒˆ์งธ ์ธ์ž์— "i'm here!!" ์ด ๋“ค์–ด๊ฐ„ resolve๊ฐ€ ์‹คํ–‰์ด ๋˜๋ฉฐ.

์ด ์ธ์ž๋Š” .then์˜ ์ฒซ๋ฒˆ์งธ ์ธ์ž๋Š” ํ•จ์ˆ˜์ด๊ณ , ์ด ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋ฐ›์•„์„œ ์ฝ˜์†”์— ์ฐํžˆ๊ฒŒ ๋œ๋‹ค.

then

.then์€ ํ”„๋กœ๋ฏธ์Šค์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•˜๊ณ  ๊ธฐ๋ณธ์ด ๋˜๋Š” ๋ฉ”์„œ๋“œ.

promise.then(
  function(result) { /* ๊ฒฐ๊ณผ(result)๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค */ },
  function(error) { /* ์—๋Ÿฌ(error)๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค */ }
);

.then์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์ดํ–‰๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์ด๊ณ , ์—ฌ๊ธฐ์„œ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์œผ๋ฉฐ.

.then์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๊ฑฐ๋ถ€๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์ด๊ณ , ์—ฌ๊ธฐ์„œ ์—๋Ÿฌ๋ฅผ ๋ฐ›๋Š”๋‹ค.

 

๐Ÿ’ซ์˜ˆ์‹œ

let promise = new Promise(function(resolve, reject) {
  setTimeout(() => resolve("์™„๋ฃŒ!"), 1000);
});

// resolve ํ•จ์ˆ˜๋Š” .then์˜ ์ฒซ ๋ฒˆ์งธ ํ•จ์ˆ˜(์ธ์ˆ˜)๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
promise.then(
  result => alert(result), // 1์ดˆ ํ›„ "์™„๋ฃŒ!"๋ฅผ ์ถœ๋ ฅ
  error => alert(error) // ์‹คํ–‰๋˜์ง€ ์•Š์Œ
);

์ฒซ ๋ฒˆ์งธ ํ•จ์ˆ˜ ์‹คํ–‰.

ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๊ฑฐ๋ถ€๋œ ๊ฒฝ์šฐ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋‘ ๋ฒˆ์งธ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰.

์ž‘์—…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋œ ๊ฒฝ์šฐ๋งŒ ๋‹ค๋ฃจ๊ณ  ์‹ถ๋‹ค๋ฉด .then์— ์ธ์ˆ˜๋ฅผ ํ•˜๋‚˜๋งŒ ์ „๋‹ฌ.

 

catch

์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ๋งŒ ๋‹ค๋ฃจ๊ณ  ์‹ถ๋‹ค๋ฉด .then(null, errorHandlingFunction)๊ฐ™์ด null์„ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

.catch(errorHandlingFunction)๋ฅผ ์จ๋„ ๋˜๋Š”๋ฐ, .catch๋Š” .then์— null์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

let promise = new Promise((resolve, reject) => {
  setTimeout(() => reject(new Error("์—๋Ÿฌ ๋ฐœ์ƒ!")), 1000);
});

// .catch(f)๋Š” promise.then(null, f)๊ณผ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค
promise.catch(alert); // 1์ดˆ ๋’ค "Error: ์—๋Ÿฌ ๋ฐœ์ƒ!" ์ถœ๋ ฅ

.catch(f)๋Š” ๋ฌธ๋ฒ•์ด ๊ฐ„๊ฒฐํ•˜๋‹ค๋Š” ์ ๋งŒ ๋นผ๊ณ  .then(null,f)๊ณผ ์™„๋ฒฝํ•˜๊ฒŒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

function check(key) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (key === true) resolve("i'm here!!");
      else reject(new Error("No I'm not here"))
    }, 1000);
  })
}

check(true)
  .then((result) => { console.log(result); })
  .catch((error) => { console.log(error); });

 

ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด์— ๋น„๋™๊ธฐ๊ฐ€ ์ฒ˜๋ฆฌ๋œ ๊ฒฐ๊ณผ๊ฐ’์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
์ฝœ๋ฐฑ์˜ ๊ฒฝ์šฐ ๋งค๋ฒˆ ๋น„๋™๊ธฐ๋ฅผ ์‹คํ–‰ํ•ด์•ผ์ง€ ๊ทธ ๊ฐ’์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์ง€๋งŒ
ํ”„๋กœ๋ฏธ์Šค๋Š” .then ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฐ’์„ ์›ํ•˜๋Š” ๋•Œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


ํ”„๋กœ๋ฏธ์Šค์˜ 3๊ฐ€์ง€ ์ƒํƒœ(states)

ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์•Œ์•„์•ผ ํ•˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ฐœ๋…์ด ๋ฐ”๋กœ ํ”„๋กœ๋ฏธ์Šค์˜ ์ƒํƒœ(states)์ด๋‹ค.

์ƒํƒœ๋ž€ ํ”„๋กœ๋ฏธ์Šค์˜ ์ฒ˜๋ฆฌ ๊ณผ์ •์„ ์˜๋ฏธํ•˜๋ฉฐ, new Promise()๋กœ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ 3๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ–๋Š”๋‹ค.

  • Pending(๋Œ€๊ธฐ) : ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋กœ์ง์ด ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์ƒํƒœ
  • Fulfilled(์ดํ–‰) : ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜์–ด ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์ค€ ์ƒํƒœ
  • Rejected(์‹คํŒจ) : ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์ƒํƒœ

Pending(๋Œ€๊ธฐ)

๋จผ์ € ์•„๋ž˜์™€ ๊ฐ™์ด new Promise() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋Œ€๊ธฐ(Pending) ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

new Promise();
 
 

new Promise() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๊ณ , ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์ธ์ž๋Š” resolve, reject์ด๋‹ค.

new Promise(function(resolve, reject) {
  // ...
});

 

Fulfilled(์ดํ–‰)

์—ฌ๊ธฐ์„œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์ธ์ž resolve๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์‹คํ–‰ํ•˜๋ฉด ์ดํ–‰(Fulfilled) ์ƒํƒœ๊ฐ€ ๋˜๋ฉฐ.

new Promise(function(resolve, reject) {
  resolve();
});

์ดํ–‰ ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด then()์„ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

function getData() {
  return new Promise(function(resolve, reject) {
    var num = 1;
    resolve(num);
  });
}

// resolve()์˜ ๊ฒฐ๊ณผ ๊ฐ’ num์„ resolvedData๋กœ ๋ฐ›์Œ
getData().then(function(resolvedData) {
  console.log(resolvedData); // 1
});

โ€ป ํ”„๋กœ๋ฏธ์Šค์˜ '์ดํ–‰' ์ƒํƒœ๋ฅผ ์ข€ ๋‹ค๋ฅด๊ฒŒ ํ‘œํ˜„ํ•ด๋ณด๋ฉด '์™„๋ฃŒ' ์ด๋‹ค.

 

Rejected(์‹คํŒจ)

new Promise()๋กœ ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์ธ์ž๋กœ resolve์™€ reject๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ reject๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ํ˜ธ์ถœํ•˜๋ฉด ์‹คํŒจ(Rejected) ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

new Promise(function(resolve, reject) {
  reject();
});

๊ทธ๋ฆฌ๊ณ , ์‹คํŒจ ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ์‹คํŒจํ•œ ์ด์œ (์‹คํŒจ ์ฒ˜๋ฆฌ์˜ ๊ฒฐ๊ณผ ๊ฐ’)๋ฅผ catch()๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("Request is failed"));
  });
}

// reject()์˜ ๊ฒฐ๊ณผ ๊ฐ’ Error๋ฅผ err์— ๋ฐ›์Œ
getData().then().catch(function(err) {
  console.log(err); // Error: Request is failed
});

 

ํ”„๋กœ๋ฏธ์Šค ์ฒ˜๋ฆฌ ํ๋ฆ„ - ์ถœ์ฒ˜ : MDN

 


promise(ํ”„๋กœ๋ฏธ์Šค)์™€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋ฐฉ์‹๊ณผ ์ฐจ์ด๋กœ๋Š”

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

๋˜,


Promise ํด๋ž˜์Šค๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋งŒ์„ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค์— resolve๋‚˜ reject ํ•จ์ˆ˜๋“ค์ด ์ž˜ ์ •์˜๋˜์–ด ์žˆ๊ณ  ์ด๋ฅผ ์ž˜ ํ™œ์šฉํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜์ง€๋งŒ, callback pattern์€ ์ž์œ ๋„๊ฐ€ ๋†’์ง€๋งŒ template์ด ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง€๊ณ  ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๊ฐ™์€ ์ž‘์—…๋“ค์ด ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์ตœ๊ทผ์— ๋‚˜์˜จ async & await ๋ฌธ๋ฒ•์ด ์žˆ์œผ๋ฉฐ,
์กด์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ธ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์™€ ํ”„๋กœ๋ฏธ์Šค์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•˜๊ณ  ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ๊ธฐ ์ข‹์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค๋‹ˆ๋‹ค

 

 

 

๐Ÿ“š์ถœ์ฒ˜


https://danbom425.tistory.com/34

https://goodmemory.tistory.com/17

https://jcon.tistory.com/189

https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/

https://ko.javascript.info/promise-basics

https://ko.javascript.info/callbacks

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

728x90