[JavaScript] Promise 사용하기

Song·2021년 6월 27일
0

JavaScript

목록 보기
2/3

Promise 사용하기

JavaScript는 싱글 스레드로 동시 작업이 안되는데 예를 들어 Network 통신이나 파일 읽기 등
무거운 작업을 수행할 때 JS는 결과값이 반환될 때까지 계속 기다리게된다.
만약 페이지가 출력이 되야하는데 그 이전 단계인 파일 읽기가 10초가 걸린다면 그 시간동안 페이지는 출력이 안되고 백지상태로 있을 것이다.

그렇기 때문에 이때는 promise로 비동기 처리를 해줘야한다.

promise란, 비동기를 간편하게 처리해주는 Javascript 내장 객체이며
아래와 같이 상태와 단계가 나누어진다.

State(상태)

  1. Pending: promise 객체 생성 후 수행 중일 때
  2. Fulfilled: 수행 완료
  3. Rejected: 수행 실패

단계

  1. Producer: promising 객체를 생성 및 결과를 반환하는 단계
  2. Consumer: promising에서 반환된 값을 받아오는 곳

* Producer

Producer에서는 promise 객체를 생성하여 결과를 반환해준다.

promise는 클래스이므로 아래와 같이 new로 객체를 생성하고
인자로 executor 콜백함수를 전달 받는다.
이 때 executor는 resolve, reject를 전달 받는다.

const promise = new Promise((resolve, reject) => {})

아래는 setTimeout 이라는 브라우저 API를 콜백함수로 전달한 예제이다.

const promise = new Promise((resolve, reject) => { 
    setTimeout(() => 
        // 성공적인 promise 수행 완료 시 아래 resolve 실행
        resolve('ellie')
        // Error()는 에러 발생 시 에러는 나타내는 JS에서 제공하는 오브젝트
        // reject(new Error('no network'))
    ,1000)
})

* Consumer

Cosumer에서는 then, catch, finally를 이용하여 값을 받아올 수 있다.

promise
    // promise가 정상적으로 수행되었다면 resolve에서 받은 값이 value에 전달된다.
    .then((value) => {
        console.log(value)
    })
    // promise에서 오류 발생 시 에러 출력
    .catch(error => {
        console.log(error)
    })
    .finally(() => {
    // 성공, 실패 상관없이 실행되는 코드
        console.log('finally')
    })

Promise Chaining

promise chaining이란 여러개의 promise 객체를 연결하여 사용하는 것이다.
then() 메서드를 호출 시 또 다른 promise 객체가 반환된다.

fetchNumber 라는 promise 객체를 새로 만들어주자.
setTimeout 콜백 함수를 인자로 넘어주었고 성공 시 1이라는 값이 반환된다.

const fetchNumber = new Promise((resolve, reject) => {
    setTimeout(() => {resolve(1)}, 1000)
    }
)

생성한 promise 객체의 then 메소드를 호출한다.

fetchNumber
     //num 변수에 위 코드에서 반환한 1이 할당되고 곱하기 2를 해준다.
    .then(num => num * 2)   // 2
     // 위에서 반환된 값이 아래 num에 할당되어 곱하기 3를 한 후 num에 다시 전달한다.
    .then(num => num * 3)   // 6
    // then은 값을 전달하지만 promise도 전달할 수 있다.
    .then(num => {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve(num - 1), 1000)   // 5
        })
    })
   // 최종 num의 값을 콘솔로 출력한다.
    .then(num => console.log(num))  // 5

Error Handling

promise 사용 중 에러 발생 시 에러를 출력하는 방법도 있지만
promise chaining이 끊김없이 계속 이어질 수 있도록 대체 값을 반환할 수도 있다.

Producer

  const getHen  = () => 
        new Promise((resolve, reject) => {
            setTimeout(() => resolve('닭'), 1000)
        })   
  const getEgg = hen => 
    new Promise((resolve, reject) => {
      	에러 발생!!
      	setTimeout(() => reject(new Error(`error! ${hen} => egg`)), 1000)
        //setTimeout(() => resolve(`${hen} => egg `), 1000)
        })   
  const cook = egg => 
    new Promise((resolve, reject) => {
        setTimeout(() => resolve(`${egg} => fries `), 1000)
        })  

Consumer

getHen()
  // getHen()에서 전달받은 닭을 이용해서 getEgg에 전달
  .then(hen => getEgg(hen))
  // getEgg에서 에러 발생 시 'bread'를 대신 반환함으로서 chain이 끊기지않고 
  // 다음 프로미스 객체로 전달된다.
  .catch(error => {
  return 'bread'
  })
   // getEgg()에서 전달받은 달걀을 이용해서 cook에 전달
  .then(egg => cook(egg))
  .then(meal => console.log(meal))

이 모든 예제는 유튜브 드림코딩 엘리님의 가르침을 참고하였다.
출처 : 갓엘리님의 드림코딩 - 자바스크립트 프로미스 개념편

profile
Learn From Yesterday, Live Today, Hope for Tomorrow

0개의 댓글