Promise

Dongmin·2024년 7월 23일
0

스터디

목록 보기
4/4

Promise의 도입

Promise는 기존 콜백함수의 중첩으로 처리하던 비동기 함수 호출 방식을 대신하여 ES6에서 도입된 모듈이다.

아래는 기존 콜백함수의 중첩으로 3초마다 콘솔에 숫자를 보여주는 로직이다. 함수의 중첩된 구문을 사용하게 되므로 가독성이 떨어지는 콜백 지옥(Callback Hell) 이 발생한다.

setTimeout(() => {
  console.log("1");
  setTimeout(() => {
    console.log("2");
    setTimeout(() => {
      console.log("3");
      setTimeout(() => {
        console.log("4");
      }, 3000);
    }, 3000);
  }, 3000);
}, 3000);

이를 Promise로 변경하면

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

delay(3000)
  .then(() => {
    console.log("1");
    return delay(3000);
  })
  .then(() => {
    console.log("2");
    return delay(3000);
  })
  .then(() => {
    console.log("3");
    return delay(3000);
  })
  .then(() => {
    console.log("4");
  });

이렇게 chaining으로 표현 가능하다.
기존 콜백 중첩 형태보다 가독성이 좋고 코드 수정에도 훨씬 용이하다.

Promise 모듈의 상태

Promise에는 3가지 상태가 존재한다.

  • pending : 비동기 연산 대기(진행) 상태
  • fulfilled : 비동기 연산 성공 상태
  • rejected : 비동기 연산 실패 상태

연산이 종료된 상태인 fulfilled와 rejected가 발생하게 되면 핸들러, 즉 비동기 연산이 완료되면 실행될 함수는 태스크큐에서 콜백큐로 잠시 이동하여 이벤트 루프가 콜스택이 비어있음을 감지해 옮겨주기 전까지 보관되는데 이를 Promise 객체 후속 처리 메소드인 then, catch, finally가 실행하게 된다.

Promise 정적 메소드

Promise는 5가지 정적 메소드를 제공한다.

1. Promise.resolve
fullfilled 상태에 대한 결과값을 반환한다.

const promise = Promise.resolve("성공");
// new Promise(resolve => resolve('성공'))
promise.then((message) => console.log(message));

2. Promise.reject
rejected 상태에 대한 결과값을 반환한다.

const promise = Promise.reject("실패");
// new Promise((_,reject) => reject('실패'))
promise.catch((errorMessage) => console.log(errorMessage));

3. Promise.all
여러 Promise가 담긴 이터러블 객체를 인자로 받아 병렬로 실행해 모두 resolve(fullfilled)될 때까지 실행하여 배열에 담아 반환한다. 또는 하나라도 rejected되면 rejected 상태로 즉시 실행을 완료한다.

Promise.all([
  new Promise((resolve) => setTimeout(() => resolve(1), 1000)),
  new Promise((resolve) => setTimeout(() => resolve(2), 2000)),
  new Promise((resolve) => setTimeout(() => resolve(3), 3000)),
])
  .then(console.log) // [1, 2, 3]
  .catch(console.log);

4. Promise.race
Promise.all과 형태는 비슷하지만 먼저 끝나는 비동기 연산의 결과값만을 반환한다.

Promise.all([
  new Promise((resolve) => setTimeout(() => resolve(1), 1000)),
  new Promise((resolve) => setTimeout(() => resolve(2), 2000)),
  new Promise((resolve) => setTimeout(() => resolve(3), 3000)),
])
  .then(console.log) // 1
  .catch(console.log);

5. Promise.allSettled
Promise.all이 하나라도 rejected 상태가 되면 즉시 수행을 종료하는 것과 달리 Promise.allSettled는 연산 상태에 상관 없이 연산을 모두 수행한 후, 상태와 결과값을 담아 반환한다.
이때, fulfilled는 value 라는 프로퍼티에, rejected는 reason이라는 프로퍼티에 결과값 혹은 처리결과를 담게 된다.

Promise.allSettled([
  new Promise((resolve) => setTimeout(() => resolve(1), 1000)),
  new Promise((_, reject) => setTimeout(() => reject(2), 2000)),
]).then(console.log);
// console.log 결과
[
  { status: 'fulfilled', value: 1 },
  { status: 'rejected', reason: 2 }
]

참조
[JavaScript] Promise란?
[JavaScript] 프로미스(Promise)란

profile
주니어 프론트엔드 개발자의 생존기

0개의 댓글