자바스크립트 Promise란

Woody·2025년 8월 17일
0

매일메일

목록 보기
10/13

오늘의 질문

자바스크립트 Promise에 대해서 아는 대로 설명해주세요.

내답변

Promise 란 약속이라는 이름에 맞게 어떤 동작을 걸어두었을때 수행해주는 방식이다.

promise 함수라고도 불리며 동작에 따라 pending resolve reject 의 상태를 확인할 수 있다. 동작중일때는 pending, 성공시에는 resolve 실패시 reject 로 동작한다.

promise 가 수행된 이후 동작할 동작에는 .then 을 통해서 동작을 이을 수 있다.
then 에 수행되는 동작에는 resolve 시의 동작, reject 시의 동작을 모두 설정할 수 있다.

유명한 이론으로 promise 지옥 이라는 이론이 있는데 then 을 남발했을때의 동작이다. 비동기 작업을 진행하고 싶을때 promise 에 작업을 걸고 그걸 스탭대로 두게 되면 1번작업 후 then, 2번 작업 후 then 방식으로 넣게 되고. 이러한 then 이 길어지게 되면 결국 어떤곳에서의 문제가 있는지 알기 어려워 진다는 이론이다.

이를 해결하기 위해 명확한 단계를 두고 설계해야 한다.

오늘정답

자바스크립트의 Promise 는 비동기 작업을 관리하고, 해당 작업의 성공 또는 실패 결과를 나중에 사용할 수 있도록 하는 객체이다. Promise 는 비동기 작업의 완료 여부를 약속해주는 개념이라고 할 수 있다.

자바스크립트는 비동기 처리를 위한 콜백 함수를 많이 사용한다. 하지만 콜백 함수는 코드가 복잡해짐에 따라 콜백이 중첩되는 '콜백 지옥' 문제를 야기할 수 있다. promise는 이러한 비동기 처리의 가독성을 높히고, 코드의 흐름을 명확하게 관리할 수 있도록 도와주는 방식이다.

Promise에는 3가지 상태가 있다.
비동기 작업이 아직 완료되지 않은 초기 상태인 Pending
비동기 작업이 성공적으로 완료되어 값을 반환한 Fulfilled
비동기 작업이 실패하여 오류를 반환한 Rejectd 이다.

Promise 객체는 비동기 작업을 수행할 함수를 인자로 받아서 실행하며, 이 함수는 resolve() 와 reject() 라는 두 가지 콜백을 받는다.

resolve() 는 비동기 작업이 성공했을 때 값을 전달하여 Promise를 fulfilled 상태로 전환하고, reject()는 비동기 작업이 실패했을 때 오류를 전달하여 Promise를 rejected 상태로 전환한다.

Pending 상태에서 Fulfilled나 Rejected 상태로 전환되면, 이후에는 다른 상태로 전환되지 않으며 , 그 결과 값을 통해 해당 작업의 성공 여부를 알 수 있다.

Promise 는 코드의 가독성을 높이고, 비동기 작업의 흐름을 제어하는 데에 매우 유용하다. 특히 여러 개의 Promise를 순차적으로 연결할 수도 있고 Promise.all() 이나 allSettled() 와 같은 메서드를 통해 병렬로 비동기 작업을 처리할 수도 있다.

Promise의 단점
복잡한 에러처리
Promise는 단일 체인에서는 에러 처리가 간단하지만, 여러 Promise가 중첩되거나 서로 다른 비동기 흐름에서 에러가 발생할 경우 복잡도가 증가할 수 있다. 예를들어 then() 체인 내의 중간 단계에서 오류가 발생하면 catch 블록에서 캐치가 가능하지만, 특정 단계에서만 발생하는 에러를 세밀하게 다루기가 어렵다.

콜백지옥해결이 어려움
어느정도 해결은 가능하지만, 복잡한 중첩에서는 여전히 then() 메서드가 연속해서 사용되며 가독성이 떨어진다. 이를 async/await 을 통해 개설이 가능하다

피드백

  1. Promise 의 정확한 정의

Promise 는 단순히 '약속' 이 아닌 비동기 작업의 결과 를 나타내는 객체

한 번 Fulfilled나 Rejected가 되면 상태는 불변이다.

  1. Promise 생성과 사용법 예시
// Promise 생성 예시
const myPromise = new Promise((resolve, reject) => {
  // 비동기 작업
  if (성공) {
    resolve(결과값);
  } else {
    reject(에러);
  }
});
  1. 에러 처리 메서드
    .catch() 메서드와 .finally() 메서드.

catch의 경우 에러만 다루고 싶을때 사용하는 방식이다. then 에 null 을 전달하는것과 동일하게 작동하며 에러에 대한 값을 가져온다

let promise = new Promise((resolve, reject) => {
  setTimeout(() => reject(new Error("에러 발생!")), 1000);
});

// .catch(f)는 promise.then(null, f)과 동일하게 작동합니다
promise.catch(alert); // 1초 뒤 "Error: 에러 발생!" 출력

finally 는 프로미스가 처리되고 나서 항상 실행되는 방식이다.

new Promise((resolve, reject) => {
  /* 시간이 걸리는 어떤 일을 수행하고, 그 후 resolve, reject를 호출함 */
})
  // 성공·실패 여부와 상관없이 프라미스가 처리되면 실행됨
  .finally(() => 로딩 인디케이터 중지)
  .then(result => result와 err 보여줌 => error 보여줌)

다만 finally는 .then(f,f) 와 완전히 같지는 않다.
finally 에서는 프로미스가 이행되었는지 거부되었는지 알 수 없다. 성공 실패와는 관련이 없기 때문.

  1. 명확한 용어의 차이
  • Promise 함수보다는 Promise 객체가 맞는 표현
  • Promise 지옥이 아닌 '콜백지옥' 을 이야기 해야 함
  • then 체이닝은 문제가 아니며 콜백 지옥의 해결책으로 꼽힘
  1. promise를 더 간결하게 다루는 현대적 문법인 async/await 문법
async function fetchData() {
  try {
    const result = await somePromise();
    return result;
  } catch (error) {
    console.error(error);
  }
}
  1. 마이크로태스크 큐

Promise 의 경우 javascript 의 이벤트 루프의 핵심 구성요소인 마이크로 태스크큐에서 대기하게 된다.
동작예시

console.log('1. 시작');

setTimeout(() => {
  console.log('2. setTimeout (태스크 큐)');
}, 0);

Promise.resolve().then(() => {
  console.log('3. Promise (마이크로태스크 큐)');
});

console.log('4. 끝');

// 출력 순서:
// 1. 시작
// 4. 끝
// 3. Promise (마이크로태스크 큐)
// 2. setTimeout (태스크 큐)

실행 순서:
1. 현재 실행 중인 모든 동기 코드 완료
2. 마이크로태스크 큐의 작업 처리
3. 태스크 큐에서 작업처리
4. 다시 마이크로태스크 큐 확인(2번)


답변 스크립트

자바스크립트의 Promise는 비동기 작업의 최종 결과를 나타내는 객체입니다.
세 가지 상태가 있는데, 작업이 진행 중일 때는 pending, 성공하면 fulfilled, 실패하면 rejected 상태가 됩니다.
한 번 결과가 결정되면 상태는 변하지 않고 불변성을 가집니다.

Promise는 then, catch, finally 메서드를 통해 성공, 실패, 후처리를 각각 다룰 수 있습니다.
이를 통해 기존 콜백 방식에서 발생하던 콜백 지옥 문제를 해결하고, 코드 흐름을 더 읽기 쉽게 만들었습니다.
또한 Promise.all, race, allSettled, any 같은 정적 메서드를 이용하면 여러 비동기 작업을 병렬적으로 관리할 수 있습니다.

마지막으로, ES2017에 추가된 async/await 문법은 Promise를 기반으로 더 직관적인 코드 작성 방식을 제공하여,
가독성과 에러 처리를 크게 개선해줍니다.

profile
프론트엔드 개발자로 살아가기

0개의 댓글