그순간

Promise

강동혁·2026년 9월 17일·7 조회

Promise란?

Promise는 비동기 작업을 처리할 때 사용되는 자바스크립트의 객체입니다.

Promise를 이해하기 위해서는 먼저 비동기 작업이 무엇인지 알아야 합니다.

비동기 작업?

비동기 프로그래밍을 설명하기 전에 먼저 동기 프로그래밍부터 알아보겠습니다. 동기 프로그래밍은 작업을 한 번에 하나씩, 순서대로 실행하는 방식입니다.

예를 들어 다음과 같은 코드가 있다고 해보겠습니다.

console.log("1번 작업");
console.log("2번 작업");
console.log("3번 작업");

이 코드는

1번 작업
2번 작업
3번 작업

이렇게 작성한 순서대로 실행됩니다.

자바스크립트 코드는 기본적으로 이러한 동기적인 방식으로 실행됩니다.

동기 방식은 실행 순서를 따라가기 때문에 코드의 흐름을 이해하기 쉽다는 장점이 있습니다. 하지만 시간이 오래 걸리는 작업이 있다면 문제가 생길 수 있습니다.

앞의 작업이 끝날 때까지 뒤의 작업들이 모두 기다려야 하기 때문에, 전체 프로그램이 멈춘 것처럼 보일 수도 있습니다. 이러한 문제를 해결하는 데 사용하는 방식이 비동기 프로그래밍입니다.

비동기 프로그래밍은 작업이 완료되기를 기다리는 동안 다른 작업을 먼저 실행할 수 있도록 하는 방식입니다.

예를 들어 다음과 같은 코드가 있습니다.

console.log("1번 작업");

setTimeout(() => {
  console.log("2번 작업");
}, 1000);

console.log("3번 작업");

이 코드를 실행하면 결과가 이렇게 됩니다.

1번 작업
3번 작업
2번 작업

setTimeout()에 들어 있는 2번 작업은 1초가 지난 뒤 실행되도록 예약되기 때문에, 기다리지 않고 다음 코드인 3번 작업을 먼저 실행하게 됩니다.

이처럼 비동기 방식을 사용하면 작업이 완료되기를 기다리는 동안 다른 작업을 실행할 수 있습니다.

하지만 비동기 작업이 완료된 후에 실행해야 하는 작업도 있을 수 있습니다. 이런 작업을 처리하는 방법 중 하나가 비동기 콜백입니다.

비동기 콜백이란?

콜백 함수는 다른 함수에 인자로 전달되어 호출되는 함수입니다. 이러한 콜백을 비동기 작업의 결과를 처리하는 데 사용할 수 있습니다.

예시를 보면 다음과 같습니다.

function getData(callback) {
  setTimeout(() => {
    console.log("서버에서 데이터 가져옴");
    callback({ name: "동혁" }); //서버에서 가져온 데이터
  }, 2000);
}

getData((data) => {
  console.log(data.name);
});

위 코드는 실제 서버에 요청하는 대신, setTimeout()으로 데이터를 가져오는 상황을 흉내 낸 예시입니다.

getData() 함수는 callback이라는 매개변수로 함수를 받습니다.

2초 뒤에 예약된 함수가 실행되면 callback()을 호출하고, { name: "동혁" }이라는 데이터를 전달합니다.

전달된 데이터는 콜백 함수에서 data라는 매개변수로 받아 사용할 수 있습니다.

즉, 비동기 작업이 끝난 뒤 실행할 함수를 미리 전달하고, 작업이 완료되면 해당 함수를 실행하는 방식입니다.

하지만 이런 비동기 콜백이 계속 중첩되면 문제가 생기는데요. 이를 콜백 지옥이라고 합니다.

콜백 지옥

login("동혁", (username) => {
  console.log(`${username}님 로그인 완료`);
  getUserInfo(username, (user) => {
    console.log(`${user.name}님의 정보를 불러왔습니다.`);
    getPosts(user.id, (posts) => {
      console.log(`${posts.length}개의 게시글을 불러왔습니다.`);
      getComments(posts[0].id, (comments) => {
        console.log(`${comments.length}개의 댓글을 불러왔습니다.`);
      });
    });
  });
});

이렇게 비동기 콜백이 계속 중첩되면 코드는 점점 오른쪽으로 들어가고, 구조가 복잡해져 코드를 이해하기 어려워집니다.

이런 중첩을 줄이기 위해 사용하는 것이 바로 Promise입니다.

Promise의 상태

Promise를 사용하면 비동기 작업의 성공과 실패를 하나의 객체로 관리할 수 있습니다. 이를 이해하기 위해 먼저 Promise가 가지는 상태를 알아보겠습니다.

Promise는 크게 3가지 상태를 가집니다.

  • Pending

Pending은 아직 성공이나 실패가 결정되지 않은 대기 상태입니다. 예를 들어 서버에 데이터를 요청했지만 아직 응답이 오지 않았다면 Pending 상태라고 할 수 있습니다.

  • Fulfilled

Fulfilled는 작업이 성공적으로 완료된 상태입니다.

작업이 정상적으로 끝났으며, 결과값을 사용할 수 있는 상태입니다.

  • Rejected

Rejected는 작업이 실패한 상태입니다.

네트워크 오류가 발생하는 등 작업을 정상적으로 완료하지 못했을 때의 상태입니다.

Promise 사용법

정리하면 Promise는 다음과 같이 만들 수 있습니다.

const promise = new Promise((resolve, reject) => {
  const success = true;

  if (success) {
    resolve("작업 성공");
  } else {
    reject("작업 실패");
  }
});

new Promise()에 전달하는 함수는 resolve와 reject라는 두 함수를 매개변수로 받습니다.

resolve()에는 작업의 성공 결과를 전달하고, reject()에는 실패 이유를 전달합니다.

참고로 new Promise()에 전달한 함수 자체는 즉시 실행됩니다. 이부분을 executor함수라고 합니다.

위 예시도 기다리는 작업이 없기 때문에 바로 성공 상태가 됩니다.

Promise의 결과는 then(), catch(), finally()를 사용하여 처리할 수 있습니다.

then()

then()에는 Promise가 성공했을 때 실행할 콜백 함수를 전달할 수 있습니다.

즉, Promise의 상태가 Fulfilled가 되면 해당 콜백이 실행됩니다.

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

코드에서 resolve("작업 성공")을 실행했다면 result에는 "작업 성공"이라는 값이 들어옵니다.

catch()

catch()에는 Promise가 실패했을 때 실행할 콜백 함수를 전달합니다.

즉, Promise의 상태가 Rejected가 되면 해당 콜백이 실행됩니다.

promise.catch((error) => {
  console.log(error);
});

만약 Promise에서

reject("작업 실패");

가 실행되었다면 "작업 실패"라는 값이 error로 전달됩니다.

finally()

finally()에는 Promise의 성공 여부와 상관없이, 처리가 끝난 뒤 실행할 콜백 함수를 전달합니다.

promise.finally(() => {
  console.log("작업 종료");
});

그래서 로딩 화면을 종료하거나 작업이 끝난 뒤 공통적으로 실행해야 하는 코드가 있을 때 사용할 수 있습니다.

전체적으로 사용하면 다음과 같습니다.

promise
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    console.log(error);
  })
  .finally(() => {
    console.log("작업 종료");
  });

위 코드에서는 성공하면 then()의 콜백이 실행되고, 실패하거나 앞의 then() 콜백에서 오류가 발생하면 catch()의 콜백이 실행됩니다.

그다음 finally()의 콜백에서 공통 마무리 작업을 실행합니다.

정리

Promise를 사용하면 콜백의 중첩을 줄이고 비동기 작업을 순서대로 연결할 수 있습니다.

또한 catch()로 연결된 작업의 에러를 처리하고, finally()로 공통 마무리 작업을 실행할 수 있습니다.

마지막으로 정리하면 Promise는 비동기 코드의 흐름과 에러 처리를 더 명확하게 만들어주는 자바스크립트 객체입니다.

목차