프로그래밍/Js

Promise 와 async await 대해 자세하게 알아보자.

소행성왕자 2024. 10. 24. 14:36

Promise는 JavaScript에서 비동기 작업을 처리하기 위한 객체입니다. 

Promise의 주요 특징과 기본 개념은 다음과 같습니다:

상태(State)

Promise는 세 가지 상태 중 하나를 가집니다. 이는 resolve 와 reject 호출함으로써 반영됩니다.

  • Pending (대기) :  Promise가 생성된 초기 상태입니다. 비동기 작업이 아직 완료되지 않은 상태를 의미합니다. new Promise()로 Promise를 생성하면 이 상태가 됩니다. 
  • Fulfilled (이행) : 비동기 작업이 성공적으로 완료된 상태입니다. Promise 내부에서 resolve 함수가 호출되면 이 상태가 됩니다. .then() 메서드를 통해 처리 결과를 받을 수 있습니다. 
  • Rejected (거부) : 비동기 작업이 실패하거나 오류가 발생한 상태입니다. Promise 내부에서 reject 함수가 호출되면 이 상태가 됩니다. .catch() 메서드를 통해 오류를 처리할 수 있습니다.

Promise 객체는 아래와 같이 생성합니다.

const promise = new Promise((resolve, reject) => {
  // 비동기 작업 수행
  // 성공 시: resolve(결과)
  // 실패 시: reject(에러)
});

메서드

  • then(): 작업이 성공했을 때 실행할 콜백 함수를 등록
  • catch(): 작업이 실패했을 때 실행할 콜백 함수를 등록
  • finally(): 작업의 성공/실패 여부와 관계없이 실행할 콜백 함수를 등록

Promise의 상태는 한 번 변경되면 더 이상 바뀌지 않습니다(불변성).

Promise를 사용하면 콜백 지옥을 피하고, 비동기 코드를 보다 깔끔하고 관리하기 쉽게 작성할 수 있습니다. 

또한 async/await 문법과 함께 사용하여 더욱 직관적인 비동기 코드 작성이 가능합니다.

async/await 를 사용하여 Promise 사용하는 예제를 알아보도록 하겠습니다.

const delay = ms => {
    return new Promise((resolve, reject) => {
        setTimeout(_ => {
            if(Math.random() > 0.5) resolve('성공');
            else reject(new Error('시간초과 에러'));
        }, ms);
    });
}

(async _ => {
    console.log('start');
    try {
        const res = await delay(3000);
        console.log('결과:', res);
    } catch(e) {
        console.log('에러:', e.message);
    } finally {
        console.log('종료 - 성공이든 실패든');
    }
    console.log('end');
})();

위 코드에서 즉시 실행 함수(IIFE)를 사용한 주된 이유는 async/await를 최상위 레벨에서 사용하기 위해서입니다.

JavaScript에서 async/await는 일반적으로 함수 내부에서만 사용할 수 있습니다.

그러나 최상위 레벨(전역 스코프)에서는 직접 사용할 수 없습니다.

이를 해결하기 위해 즉시 실행 함수를 사용했습니다.

즉시 실행 함수 (IIFE) 이점

  • async/await 사용 가능: 함수 내부에서 async/await를 사용할 수 있게 됩니다.
  • 코드 격리: 즉시 실행 함수 내부의 변수들은 전역 스코프를 오염시키지 않습니다.
  • 모듈화: 관련된 비동기 로직을 하나의 블록으로 묶을 수 있습니다.
  • 즉시 실행: 코드가 정의되자마자 바로 실행됩니다.

Promise 에서 resolve 호출을 안하면 ?

Promise 상태: Promise는 'pending' 상태로 남게 됩니다. 즉, Promise가 이행(fulfilled)되거나 거부(rejected)되지 않고 미해결 상태로 유지됩니다. 

올바른 Promise 사용을 위해서는 비동기 작업이 완료되면 반드시 resolve() 또는 reject()를 호출해야 합니다. 이를 통해 Promise의 상태를 적절히 변경하고, 후속 처리를 가능하게 만들어야 합니다