생활정보

자바스크립트 비동기 처리와 Promise 이해

최근 자바스크립트의 비동기 처리 방식에 대한 이해는 웹 개발에 필수적입니다. 비동기 프로그래밍은 효율적인 리소스 사용과 사용자 경험을 극대화할 수 있도록 돕기 때문에 많은 개발자들이 이 주제에 대한 깊은 이해가 필요합니다. 이번 글에서는 자바스크립트의 비동기 처리 방식 중 콜백 함수와 프로미스를 비교하여 설명하겠습니다.

비동기 처리란?

비동기 처리는 자바스크립트에서 시간 소모가 큰 작업을 수행하는 동안 다른 코드를 계속 실행할 수 있는 기능을 의미합니다. 동기 처리와는 달리, 비동기 방식은 요청한 작업의 완료를 기다리지 않고 다음 작업으로 넘어가게 해 줍니다.

동기와 비동기의 차이

동기(Synchronous) 방식에서는 한 작업이 끝나야 다음 작업이 시작됩니다. 반면, 비동기(Asynchronous) 방식에서는 요청을 하고 그 결과를 기다리지 않고 바로 다음 작업을 실행할 수 있습니다. 이렇게 함으로써 웹 애플리케이션의 응답성을 높이고, 대기 시간을 최소화할 수 있습니다.

  • 동기: 하나의 작업이 완료될 때까지 대기
  • 비동기: 작업이 끝나지 않아도 다음 작업 실행

콜백 함수의 활용

비동기 처리를 구현하기 위한 전통적인 방법 중 하나는 콜백 함수를 사용하는 것입니다. 콜백 함수는 다른 함수에 인자로 전달되어 특정 시점에서 호출되는 함수입니다. 그러나 콜백 함수를 사용할 경우 “콜백 지옥”이 발생할 수 있습니다. 이는 중첩된 함수 호출로 인해 코드가 복잡해지고 가독성이 떨어지는 현상을 가리킵니다.

예를 들어, 다음과 같은 코드가 있다고 합시다:


function fetchData(callback) {
  setTimeout(() => {
    const data = "데이터 수신 완료";
    callback(data);
  }, 1000);
}
fetchData((data) => {
  console.log(data);
});

이 경우, fetchData 함수가 호출되고, 1초 후에 콜백이 실행됩니다. 하지만 추가적인 비동기 작업이 필요할 때, 이러한 중첩은 코드의 복잡성을 증가시킬 수 있습니다.

Promise의 등장

이러한 문제를 해결하기 위해 등장한 것이 바로 프로미스(Promise)입니다. 프로미스는 비동기 작업의 완료 상태 및 결과 값을 나타내는 객체로, 성공(resolve) 또는 실패(reject) 상태를 기반으로 결과를 반환합니다. 이를 통해 더 깔끔하고 읽기 쉬운 코드를 작성할 수 있습니다.


const fetchDataPromise = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = "데이터 수신 완료";
      resolve(data); // 성공
    }, 1000);
  });
};
fetchDataPromise()
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });

위의 코드에서 promise를 통해 비동기 작업의 결과를 다루는 방식이 더욱 명확해졌습니다. 또한, 여러 개의 비동기 작업을 연결하는 “프로미스 체이닝”을 통해 코드의 가독성 또한 향상되었습니다.

프로미스의 상태

프로미스는 다음과 같은 세 가지 상태를 갖습니다:

  • Pending: 초기 상태, 이행되지도 거부되지도 않은 상태
  • Fulfilled: 비동기 작업이 성공적으로 완료된 상태
  • Rejected: 비동기 작업이 실패한 상태

프로미스 상태를 기반으로 사용하는 후속 처리 메서드는 다음과 같습니다:

  • .then(): 비동기 작업이 성공적으로 완료된 경우 실행됩니다.
  • .catch(): 비동기 작업이 실패한 경우에 호출됩니다.
  • .finally(): 작업의 성공 여부와 관계없이 항상 실행됩니다.

Promise.all()과 Promise.race()

여러 개의 프로미스를 동시에 처리하고 싶을 때는 Promise.all()이나 Promise.race()를 사용할 수 있습니다. Promise.all()은 모든 프로미스가 이행될 때까지 기다린 후 모든 결과를 배열 형태로 반환합니다. 반면, Promise.race()는 가장 먼저 완료된 프로미스의 결과를 반환합니다.


const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'foo'));
Promise.all([promise1, promise2]).then((values) => {
  console.log(values); // [3, 'foo']
});

위 예시에서는 두 개의 프로미스를 동시에 처리하고 결과를 출력합니다.

async/await로 간결하게

자바스크립트에서는 async/await 구문을 통해 프로미스를 더욱 쉽게 다룰 수 있습니다. async 함수 내에서 await 키워드를 사용하면 비동기 작업이 완료될 때까지 기다릴 수 있으므로, 마치 동기 코드처럼 코드를 작성할 수 있습니다.


async function getData() {
  const data = await fetchDataPromise();
  console.log(data);
}
getData();

이처럼 async/await 구문을 활용하면 비동기 코드를 더욱 간결하고 이해하기 쉽게 표현할 수 있습니다. 이러한 방식은 코드의 가독성을 높이고, 유지보수 또한 수월하게 만들어 줍니다.

마무리

자바스크립트의 비동기 처리 방식은 웹 개발에서 매우 중요한 요소입니다. 특히, 콜백 함수, 프로미스, 그리고 async/await의 사용법을 잘 이해하고 활용한다면 더 나은 품질의 코드를 작성할 수 있을 것입니다. 비동기 프로그래밍 기술을 익혀 나가면서, 효율적인 웹 애플리케이션 개발에 한 걸음 더 나아가 보시길 바랍니다.

자주 묻는 질문 FAQ

비동기 처리란 무엇인가요?

비동기 처리는 자바스크립트에서 시간이 많이 소요되는 작업을 진행하는 동안, 다른 코드가 계속 실행될 수 있도록 해주는 기능입니다.

동기와 비동기의 차이는 무엇인가요?

동기 방식은 한 작업이 끝날 때까지 대기하는 반면, 비동기 방식은 작업이 진행 중이라도 다음 작업을 실행할 수 있습니다.

콜백 함수는 어떻게 사용하나요?

콜백 함수는 다른 함수에 인자로 전달되어 특정 이벤트 발생 시 호출되는 함수입니다. 비동기 처리를 위해 많이 사용됩니다.

프로미스는 무엇인가요?

프로미스는 비동기 작업의 상태를 표현하는 객체로, 성공하거나 실패한 결과를 가지고 있습니다. 이를 통해 더 깔끔한 코드 작성을 가능하게 합니다.

async/await 구문은 어떤 역할을 하나요?

async/await 구문을 사용하면 비동기 작업을 동기적으로 처리할 수 있게 해주며, 코드 가독성이 향상되고 작성이 더 간단해집니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다