[Javascript] Promise

youngseo·2022년 2월 18일
0

Javascript

목록 보기
23/46

Promise

지난 포스팅에 이어, 자바스크립트의 비동기처리로 인한 문제점 해결을 도와주는 방법인 Promise에 대해 공부를 해보도록 하겠습니다.

Promise는 미래에 성공하거나 실패할만한 값을 가지는 비동기 연산을 돕는 객체입니다. 또한 이 Promise객체는 "대기", "이행", "실패" 세가지 상태를 갖습니다.

  • 대기(Pending): 비동기 처리 로직을 이행하기도 실패하지도 않은 초기 상태.
  • 이행(Fulfilled): 비동기 처리가 성공해 프로미스가 결과 값을 반환해준 상태.
  • 실패(Rejected): 비동기 처리가 실패하거나 오류가 발생한상태.

Promise흐름

MDN

대기 중인 Promise는 값과 함께 이행이 될 수도 실패 될 수도 있습니다. 이렇게 이행이나 실패 될 경우 Promisethen()메서드로, 실패한 경우 catch()메서드로 그 값이 전달되게 됩니다.

1. Promise.resolve() & Promis.reject()

Promise.resolve(value)는 결괏값이 value인 이행 상태 Promise를 생성하며, Promise.reject(error)는 결과값이 error인 거부 상태 Promise를 생성합니다.

예제를 보면서 다뤄보도록 하겠습니다

const promiseResolve = Promise.resolve('성공')
const promiseReject = Promise.reject('실패')
promiseResolve
.then((resolve) => {
  console.log('1회', resolve)
  return promiseResolve
})
.then((resolve) => {
  console.log('2회', resolve)
  return promiseResolve
}).then((resolve) => {
  console.log('3회', resolve)
  return promiseResolve
})
코드 실행 결과 
1회 성공 
2회 성공 
3회 성공
▹Promise {<fulfilled>: '성공'}

이번에는 2회 째 리턴 값으로 promiseReject를 넣어보겠습니다.

promiseResolve
.then((resolve) => {
  console.log('1회', resolve)
  return promiseResolve
})
.then((resolve) => {
  console.log('2회', resolve)
  return promiseReject
}).then((resolve) => {
  console.log('3회', resolve)
  return promiseResolve
})
코드 실행 결과 
1회 성공 
2회 성공 
▹Promise {<rejected>: '실패'}

코드 실행 결과 2회까지만 성공을 하고 이후 실패를 하는 것을 확인할 수 있습니다.

그렇다면 마지막으로 reject리턴시 catch()메서드를 사용하면 결과 값이 어떻게 출력이 되는지 확인을 해보도록 하겠습니다.

promiseResolve
.then((resolve) => {
  console.log('1회', resolve)
  return promiseResolve
})
.then((resolve) => {
  console.log('2회', resolve)
  return promiseReject
})
.catch((reject) => {
  console.log('3회', reject)
  return promiseResolve
})
코드실행결과
1회 성공
2회 성공
3회 실패

코드 실행 결과 catch()사용 시 3회까지 잘 실행이 되고 실패가 출력되는 것을 확인할 수 있습니다.

사실, 이번에 다룬 Promise 메서드 Promise.resolvePromise.rejectasync/await 문법이 생긴 후로 쓸모없어졌기 때문에 근래에는 거의 사용하지 않는 추세이긴 합니다.

async/await 문법은 다음 포스팅에서 공부해보도록 하겠습니다.

2. 콜백함수와 프로미스화

콜백을 받는 함수를 프로미스를 반환하는 함수로 바꾸는 것을 '프라미스화(promisification)'라고 합니다. 이렇게 만들어진 프로미스 객체는 콜백함수의 결과에 따라 이행 또는 실패 상태의 프로미스를 반환합니다.

코드를 작성하다보면 프로미스가 콜백함수보다 더 편리한 것을 확인할 수 있습니다. 이전 포스팅에서 작성했던 콜백함수를 이용한 코드를 리팩토링하며 살펴보도록 하겠습니다.

콜백함수

function setTimeoutWithCallback(callbackFunc) {
  setTimeout(() => {
    console.log('2');
    callbackFunc()
  },1000);
}

console.log('1');

setTimeoutWithCallback(() => console.log('3'))

Promisification(프로미스화)

const one = Promise.resolve('1');
const two = new Promise((resolve) => setTimeout(() => {
  resolve('2')
}, 2000));
const three = Promise.resolve('3');

one.then((oneRes) => {
    console.log(oneRes)
    return two;
  })
  .then((twoRes) => {
    console.log(twoRes)
    return three;
  })
  .then((threeRes) => {
    console.log(threeRes)
  })
  .finally(() => console.log('END'))

이를 아래와 같이 조금 더 확장해 코드를 작성하면 .then과 같은 사용 없이 비동기를 조금 더 명시적으로도 작성할 수도 있습니다.

const two = (delay) =>
  new Promise((resolve) =>
    setTimeout(() => {
      resolve('2')
    }, delay));

resolvereject를 모두 사용하는 간단한 예제를 하나 더 작성을 해보겠습니다.

const starbucks = function (coffeeName) {
  return new Promise((resolve, reject) => {
    if (coffeeName === '아메리카노') {
      resolve('아메리카노 한잔입니다.');
    } else {
      reject('아메리카노는 없습니다.')
    }
  })
}
starbucks('아메리')
.then((res) => console.log(res))
.catch((rej) => console.log(rej))
.finally(() => console.log('감사합니다'));
//output
아메리카노는 없습니다.
감사합니다
starbucks('아메리카노')
.then((res) => console.log(res))
.catch((rej) => console.log(rej))
.finally(() => console.log('감사합니다'));
//output
아메리카노 한잔입니다.
감사합니다

Promise를 처음 배우는 경우 새로운 용어들에 의해 아직은 어려울 수 있지만 조금이라도 친숙해진다면 자유롭게 코드를 작성할 수 있을 것입니다

참고자료


MDN
캡틴판교
change.velog
모던튜토리얼

0개의 댓글