개발기초

[자바스크립트] 프로미스 (Promise)와 async/await에 대해서

Veams 2023. 4. 20.

Promise

Promise는 자바스크립트에서 비동기적인 작업을 처리하기 위한 객체이다. 비동기 작업은 작업의 완료 시간을 예측할 수 없는 작업을 의미하며, 이러한 작업들은 종종 I/O 작업, API 호출, 타이머 등에 의해 발생한다.

 

Promise는 비동기 작업의 최종 결과값을 나타내는 객체로, 작업이 완료되었을 때(success) 또는 실패했을 때(fail) 값을 반환한다. 비동기적인 작업의 결과를 나중에 처리할 수 있도록 도와준다.  

 

상태 분류

Promise는 다음과 같은 세 가지 상태(State)를 가진다.

- 대기(Pending) 상태: 비동기 작업이 진행 중인 상태로, 아직 결과값이 결정되지 않은 상태

- 이행(Fulfilled) 상태: 비동기 작업이 성공적으로 완료되어 결과값이 반환된 상태

- 거부(Rejected) 상태: 비동기 작업이 실패하거나 오류가 발생한 상태로, 오류 객체가 반환된다.

 

Promise 객체는 비동기적인 작업이 완료되면, 이행(Fulfilled) 상태와 함께 결과를 반환한다. 이때, .then() 메소드를 이용하여 결과를 처리할 수 있다. 반면, 비동기적인 작업이 실패하면, 거부(Rejected) 상태와 함께 에러를 반환한다. 이때, .catch() 메소드를 이용하여 에러를 처리할 수 있다.

 

Promise를 사용하면 비동기 작업의 코드를 더 깔끔하게 작성할 수 있으며, 콜백 지옥(callback hell) 문제를 효과적으로 해결할 수 있다. 이는 콜백 함수를 중첩하여 사용하는 것보다 코드의 가독성과 유지보수성이 높아진다.

 

Promise를 이용한 간단한 예시

 

1. Promise 객체 생성

const myPromise = new Promise((resolve, reject) => {
  // 비동기 작업을 수행하는 코드
});

2. then() 과 catch() 메써드 사용

myPromise
  .then((result) => {
    // 작업이 성공적으로 완료됐을 때 실행되는 코드
  })
  .catch((error) => {
    // 작업이 실패했을 때 실행되는 코드
  });

3. finally() 메서드 사용 (선택적)

myPromise
  .then((result) => {
    // 작업이 성공적으로 완료됐을 때 실행되는 코드
  })
  .catch((error) => {
    // 작업이 실패했을 때 실행되는 코드
  })
  .finally(() => {
    // 작업의 성공 여부와 관계없이 항상 실행되는 코드
  });

 

예시 두 번째

function delay(ms) {
    return new Promise(function (resolve, reject) {
        if (ms > 3000) {
            reject(new Error('Too long!'));
        } else {
            setTimeout(function () {
                resolve(ms);
            }, ms);
        }
    });
}

delay(2000)
    .then(function (result) {
        console.log('Result:', result);
    })
    .catch(function (error) {
        console.error('Error:', error.message);
    });

 

위 코드에서 delay 함수는 인자로 받은 시간(ms)만큼 지연된 후에 결과를 반환하는 Promise 객체를 생성합니다. 이때, 인자로 받은 시간이 3초를 초과하면 거부(Rejected) 상태를 반환하고, 그 외에는 이행(Fulfilled) 상태를 반환합니다. 반환된 Promise 객체는 .then() 메소드와 .catch() 메소드를 이용하여 처리할 수 있습니다. .then() 메소드는 Promise 객체가 이행 상태( Fulfilled)일 때 호출되며, .catch() 메소드는 거부 상태(Rejected)일 때 호출됩니다.

 

 

Promise를 사용하면 비동기 작업을 더 쉽게 관리할 수 있으며, 여러 비동기 작업을 연결하거나 동시에 실행하는 것도 가능합니다 (예: Promise.all(), Promise.race() 등). 이를 통해 더 효율적이고 간결한 비동기 코드 작성이 가능해집니다.

 

 

async / await 

async/await는 Node.js와 자바스크립트에서 비동기 작업을 처리하기 위한 구문이다. 이 구문은 ES2017에서 도입되었으며, 기존의 Promise를 더 간결하고 가독성 높게 작성할 수 있게 해준다.

 

async/await는 비동기 작업을 마치 동기식 코드처럼 작성할 수 있게 하여, 콜백 지옥(callback hell) 문제를 해결하는 데 도움이 된다.

 

사용예시

async 키워드를 사용해 함수를 선언한다. 이를 통해 함수는 항상 Promise를 반환하게 된다.

async function myAsyncFunction() {
  // 비동기 작업을 수행하는 코드
}

 

await 키워드를 사용해 Promise가 resolve되기를 기다린다. await 키워드는 async 함수 내에서만 사용할 수 있습니다. Promise가 resolve되면 그 결과값을 반환하고, reject되면 오류를 발생시킨다.

async function myAsyncFunction() {
  try {
    const result = await someAsyncOperation();
    // 작업이 성공적으로 완료됐을 때 실행되는 코드
  } catch (error) {
    // 작업이 실패했을 때 실행되는 코드
  }
}

 

필요한 경우, await 키워드를 사용해 여러 개의 Promise를 순차적으로 실행하거나 병렬로 실행할 수 있다.

async function myAsyncFunction() {
  try {
    const result1 = await someAsyncOperation1();
    const result2 = await someAsyncOperation2();
    // 두 작업이 순차적으로 실행
  } catch (error) {
    // 작업이 실패했을 때 실행되는 코드
  }
}

async function myAsyncFunction() {
  try {
    const [result1, result2] = await Promise.all([someAsyncOperation1(), someAsyncOperation2()]);
    // 두 작업이 병렬로 실행
  } catch (error) {
    // 작업이 실패했을 때 실행되는 코드
  }
}

async/await를 사용하면 비동기 작업을 처리하는 코드를 더 직관적이고 간결하게 작성할 수 있다. 이로 인해 코드의 가독성이 향상되며, 개발자가 비동기 작업의 흐름을 쉽게 파악하고 관리할 수 있게 된다.

댓글