[JS ES6] Promise 대신 async/await

gminnimk·2025년 3월 25일

JS ES6

목록 보기
24/31

ES8에서 도입된 async/await는 기존의 Promise와 then 체인을 훨씬 쉽게 사용할 수 있도록 도와주는 문법입니다. 이를 통해 비동기 코드를 보다 동기 코드처럼 작성할 수 있습니다.


1️⃣ async 키워드

  • 역할:
    • 함수 선언 앞에 async를 붙이면 해당 함수는 자동으로 Promise를 반환합니다.
    • 즉, new Promise()를 직접 만들 필요 없이 간단하게 Promise 기반 함수를 작성할 수 있습니다.
  • 예제:
    async function 더하기() {
      1 + 1;
    }
    
    // 호출 시, 더하기() 함수는 Promise 인스턴스를 반환하므로 then을 사용할 수 있음.
    더하기().then(function() {
      console.log('더하기 성공했어요');
    });
    
    • 위 예제에서 더하기() 함수는 async가 붙어있기 때문에 자동으로 Promise를 반환합니다.
    • 결과적으로 함수 실행 후 .then()을 사용하여 후속 작업을 수행할 수 있습니다.
  • 결과값 전달:
    • 함수 내에서 return을 사용하면 해당 값이 Promise의 resolve 값으로 전달됩니다.

      async function 더하기() {
        return 1 + 1;
      }
      
      더하기().then(function(결과) {
        console.log(결과); // 2 출력
      });
      

2️⃣ await 키워드

  • 역할:
    • awaitPromise.then()의 역할을 대신합니다.
    • async 함수 내부에서 사용 가능하며, Promise가 해결(resolve)될 때까지 기다린 후 결과 값을 반환합니다.
  • 기본 사용법:
    async function 더하기(){
      var 어려운연산 = new Promise((성공, 실패) => {
        var 결과 = 1 + 1;
        성공(결과);  // Promise가 해결되며 결과값을 반환함
      });
    
      var 결과 = await 어려운연산;  // 어려운연산이 완료될 때까지 기다림
      console.log(결과);  // 2 출력
    }
    
    더하기();
    
  • 주의 사항:
    • await는 Promise가 실패(reject)하면 에러를 발생시키며, 이 경우 코드 실행이 중단됩니다.
    • 이를 방지하고 에러를 처리하려면 try...catch 구문을 사용합니다.

3️⃣ 에러 처리: try/catch와 await

  • 실패한 Promise 처리:
    • Promise가 실패할 경우 await가 에러를 던지므로, 이를 잡아내기 위해 try...catch를 사용해야 합니다.
  • 예제:
    async function 더하기(){
      var 어려운연산 = new Promise((성공, 실패) => {
        실패('에러 발생');
      });
      try {
        var 결과 = await 어려운연산;
        console.log(결과);
      } catch (e) {
        console.log('오류 처리:', e);
      }
    }
    
    더하기();
    
    • 위 코드에서 어려운연산 Promise가 실패하면, try 블록 내에서 에러가 발생하고, catch 블록에서 이를 처리합니다.

4️⃣ 실전 예제: 버튼 클릭과 Promise

예제 1: Promise 생성 후 await 사용

  • 목표: HTML의 버튼을 클릭하면 성공한 Promise를 반환하고, 콘솔에 '성공했어요' 출력하기
<button id="test">버튼</button>

<script>
  // 1. 버튼 클릭 시 성공하는 Promise 생성
  var 프로미스 = new Promise(function(성공, 실패){
    document.getElementById('test').addEventListener('click', function(){
      성공();
    });
  });

  // 2. async 함수 내부에서 await 사용하여 Promise가 해결되길 기다림
  async function 버튼누르기(){
    await 프로미스;
    console.log('성공했어요');
  }

  버튼누르기();
</script>
  • 설명:
    • 버튼이 클릭되면 이벤트 리스너 안에서 성공()이 호출되어 프로미스가 해결됩니다.
    • await 프로미스;는 프로미스가 해결될 때까지 기다리며, 이후에 console.log('성공했어요')가 실행됩니다.

예제 2: 잘못된 패턴과 주의사항

  • 잘못된 코드 예시:
    <button id="test">버튼</button>
    
    <script>
      async function 프로미스(){
        document.getElementById('test').addEventListener('click', function(){
          return '성공했어요';
        });
      }
    
      async function 버튼누르기(){
        var 결과 = await 프로미스();
        console.log(결과);
      }
    
      버튼누르기();
    </script>
    
  • 문제점:
    • async function 프로미스() 내에 이벤트 리스너의 return이벤트 리스너 함수의 반환값이지, 프로미스() 함수 자체의 반환값이 아닙니다.
    • 결국 프로미스() 함수는 아무런 동작 없이 바로 undefined를 반환하게 되어, await로 기다리는 의미가 없어집니다.
    • 올바른 방식은 Promise를 직접 생성하여 버튼 클릭 이벤트에 연결하는 것입니다.

📌 정리

  • async 키워드
    • 함수를 Promise로 감싸주며, 이를 통해 비동기 함수 작성을 간소화합니다.
  • await 키워드
    • Promise가 해결될 때까지 기다렸다가 결과값을 반환받습니다.
    • 에러 발생 시 코드 실행이 중단되므로, try/catch로 예외 처리가 필요합니다.
  • 실전 사용 팁
    • 이벤트 기반의 비동기 처리 시, Promise를 명시적으로 생성하여 await로 기다리는 패턴이 유용합니다.
    • 잘못된 패턴(예: 이벤트 리스너 내부 return 값으로 Promise를 대신하려는 시도)은 올바른 동작을 보장하지 않습니다.

0개의 댓글