[심화] 비동기 함수 Promise, async/await 파헤치기

728x90

Promise

Promise

여러 개의 비동기 작업을 순차적으로 수행할 때 콜백 함수가 중첩되어 코드의 깊이가 깊어지는 콜백 지옥을 개선

콜백 함수를 대체하고, 비동기 작업의 흐름 쉽게 제어

 

3가지 상태

Pending(대기): 비동기 처리 로직이 아직 완료되지 않은 상태

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

위 메서드를 호출한 상태

 

Fulfilled(이행): 비동기 처리가 완료되어 프로미스가 결과 값 반환해준 상태

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

resolve( )가 호출된 상태로 then( )을 이용하여 처리 결과 값을 받을 수 있음

 

Rejected(실패): 비동기 처리가 실패하거나 오류가 발생한 상태

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

reject( )가 호출된 상태로 catch( )를 이용하여 실패 처리의 결과 값을 받을 수 있음

 

전체적인 흐름

function increaseAndPrint(n) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const value = n + 1;
      if (value === 5) {
        const error = new Error();
        error.name = 'ValueIsFiveError';
        reject(error);
        return;
      }
      console.log(value);
      resolve(value);
    }, 1000);
  });
}

increaseAndPrint(0)
  .then(increaseAndPrint)  // 1
  .then(increaseAndPrint)  // 2
  .then(increaseAndPrint)  // 3
  .then(increaseAndPrint)  // 4
  .then(increaseAndPrint)  // (5여서 error > reject() 호출)
  .catch(e => {            // ValueIsFiveError
    console.error(e);      
  });

√. error 발생 위치를 명확하게 알기 어렵고, 특정 조건에 분기를 나누는 작업도 어렵다.

 

async / await

async / await

then( ) 체인이 길게 이어지면, error 발생 위치를 명확히 알기 어렵고 가독성이 떨어짐

이를 해결하기 위함

 

async

비동기 함수이고, Promise를 반환한다고 선언

반환값이 Promise가 아니더라도 Promise 객체에 넣는 것

async function hanleSubmit() {
  ...
  return paymentData;
  // return Promise.resolve(paymentData) 와 같은 결과
}

 

await

async 함수 안에서만 사용 가능

Promise를 반환하는 함수 앞에 사용하면, 해당 Promise의 상태가 바뀔 때까지 대기

> Promise가 성공 / 실패 상태로 바뀌기 전까지 다음 연산 시작하지 않음

then( )과 같은 역할이지만, 콜백 함수 필요 없음

 

에러 처리

async/await 로 동기적으로 바꿔줬으니 try/catch를 사용하여 에러를 처리

async function handleSubmit() {
      try {
        const paymentData = await paymentWidget.requestPayment({
          orderId: "id", 
          orderName: "티셔츠"
        });
        console.log(paymentData);
        // 성공 처리
        return paymentData;
      } catch (error) {
        // 에러 처리
        console.log(error.message);
      }
    }

requestPayment( )에서 실패 상태의 Promise를 반환하면, catch 블록 실행

 

 

 

 

 

 

 

 

 

728x90