[JS] 비동기 패턴(async & await, Promise)

김지윤·2023년 10월 26일

javascript

목록 보기
1/2
post-thumbnail

비동기 패턴

Promise 객체

  • 비동기 메서드에서 동기 메서드를 사용한 것과 같은 효과를 가져온다.

  • 콜백(callback) 상태에서의 가독성 문제, 에러 처리 문제에 대한 단점을 보완한 객체.
    가장 대표적인 setTimeout의 예제로 콜백 지옥을 볼 수 있다.

      function increaseAndPrint(n, callback) {
          setTimeout(() => {
          const increased = n + 1;
          console.log(increased);
          if (callback) {
            callback(increased);
          }
        }, 1000);
      }
    	
    	// 에러 처리하기가 상당히 힘들어 보임.
      increaseAndPrint(0, n => {
        increaseAndPrint(n, n => {
          increaseAndPrint(n, n => {
            increaseAndPrint(n, n => {
              increaseAndPrint(n, n => {
                console.log('끝!');
              });
            });
          });
        });
      }); 
    • increaseAndPrint에서 계속해서 자기자신을 호출하는 모습이 보인다.
      깊이가 5가 아니라 더 깊다면 더욱 복잡해질 것으로 보인다.
  • Promise 객체의 상태

    • 대기(pending) : 초기의 상태

    • 이행(fullfilled) : 이행된 상태

    • 거부(rejected) : 거부된 상태

  • Promise는 비동기 처리 시점을 명확하게 표현할 수 있다.
    따라서 보다 나은 복잡도를 보인다.(?)

    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)
      .then(increaseAndPrint)
      .then(increaseAndPrint)
      .then(increaseAndPrint)
      .then(increaseAndPrint)
      .catch(e => {
        console.error(e);
      });

    catch로 인한 오류 구문은 사실상 없어도 됨.

    • then으로 Promise 반환하며 계속 사용하고 있다.
    • 앞의 콜백으로 작성된 코드보다 처리 시점을 더 쉽게 알 수 있다.

async & await

  • Promise 를 더욱 쉽게 사용하게 해주는 문법.
  • 함수 앞에 async를 사용하면 Promise객체를 반환한다.

(예시)

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function process() {
  console.log('안녕하세요!');
  await sleep(1000); // 1초쉬고
  console.log('반갑습니다!');
}

process();
안녕하세요! (이후에 1초쉬고) 
반갑습니다!

async와 await의 사용으로 sleep()메서드의 동작을 기다린다..

없었다면, 문자열이 다 출력된 다음에 sleep()메서드가 동작한다.

안녕하세요!
반갑습니다! (이후에 1초쉰다.)
profile
프론트엔드 개발자를 준비중입니다.

0개의 댓글