[nodejs] Promise 기반 비동기 프로그래밍

JavaScript에서는 비동기 작업을 처리할 수 있는 여러 가지 방법이 존재합니다. Promise는 이러한 비동기 작업을 보다 효율적으로 다룰 수 있는 방법 중 하나로, 최근 JavaScript 개발에서 매우 중요한 요소로 자리 잡고 있습니다.

Promise란?

Promise는 JavaScript에서 비동기적인 작업을 보다 편리하게 다룰 수 있게 해주는 객체입니다. Promise 객체는 비동기 작업을 수행하고 그 결과를 나중에 처리할 수 있도록 합니다. 이렇게 하면 콜백 지옥(callback hell)에 빠지지 않고 코드를 더 읽기 쉽고 유지보수하기 좋게 만들 수 있습니다.

본래 XMLHttpRequest나 setTimeout과 같은 메서드로부터 반환된 콜백 형태의 비동기 코드를 Promise로 감싸서 처리할 수 있습니다.

Promise의 사용 방법

Promise를 사용하여 비동기 작업을 수행하는 방법은 다음과 같습니다.

  1. new Promise로 Promise 객체를 생성합니다.
  2. Promise 생성자의 콜백 함수 안에 비동기 작업을 정의합니다. 해당 작업이 완료된 후에는 resolvereject 함수 중 하나를 호출하여 작업의 성공 또는 실패를 알립니다.

예시로, 다음은 Promise를 이용하여 1초 후에 ‘Hello, world!’를 출력하는 코드입니다.

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Hello, world!');
  }, 1000);
});

myPromise.then((result) => {
  console.log(result);
});

위 코드에서는 setTimeout 함수를 사용하여 비동기적으로 1초 후에 resolve 함수가 호출되도록 하고, then 메서드를 사용하여 해당 Promise 객체가 처리될 때 수행될 작업을 정의하고 있습니다.

Promise 체이닝

Promise는 여러 개의 비동기 작업을 연결하여 순차적으로 처리하는 방식을 지원하는데, 이를 Promise 체이닝이라고 합니다. 하나의 Promise가 처리된 후 그 결과를 가지고 다시 다른 비동기 작업을 수행하는 식으로 사용할 수 있습니다.

다음은 두 개의 비동기 작업을 순차적으로 수행하여 결과를 출력하는 코드의 예시입니다.

const firstAsyncTask = () => {
  return new Promise((resolve, reject) => {
    // 비동기 작업 수행
    resolve('First task completed');
  });
};

const secondAsyncTask = (result) => {
  return new Promise((resolve, reject) => {
    // 결과를 가지고 다른 비동기 작업 수행
    resolve(result + ', Second task completed');
  });
};

firstAsyncTask()
  .then((result) => secondAsyncTask(result))
  .then((finalResult) => {
    console.log(finalResult);
  });

위 코드에서는 두 개의 Promise 객체를 연결하여 첫 번째 작업이 완료된 후에 두 번째 작업이 수행되도록 하고 있습니다.

동기적 에러 처리

Promise를 통해 비동기 작업을 수행할 때, 에러 핸들링도 간편하게 처리할 수 있습니다. Promise 객체의 catch를 이용하여 발생한 에러를 처리할 수 있습니다.

const myPromise = new Promise((resolve, reject) => {
  // 비동기 작업 수행
  if (error) {
    reject(new Error('Failed to perform async task'));
  }
  resolve('Async task completed');
});

myPromise
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    console.error(error.message);
  });

위 코드에서는 reject 함수를 호출하여 에러를 전달하고, catch 메서드를 사용하여 해당 Promise 객체에서 발생한 에러를 처리하고 있습니다.

결론

Promise는 JavaScript에서 비동기 작업을 처리할 때 콜백 지옥을 피하고 코드를 더 읽기 쉽게 만들어주는 매우 유용한 도구입니다. 최신 JavaScript 표준으로 포함되어 있어서 모던 웹 개발에서 쉽게 적용할 수 있습니다. 비동기 작업의 처리 흐름을 명확하게 해주고, 에러 처리도 간편하게 할 수 있기 때문에, 학습하고 적극적으로 활용하는 것이 좋습니다.

참고문헌: