본문 바로가기
2주차

프로미스

by yooong 2025. 4. 25.

제,,, 노트북에 붙어있던 스티커에서 그랬습니다.

사랑의 콜백지옥에 빠져볼래?

대체 그게 뭐람. 해서 적어보는 콜백 지옥을 막기 위한 프로미스.

프로미스는 자바스크립트에서 전통적인 콜백 패턴이 가진 단점을 보완하며 비동기 처리 시점을 명확하게 표현할 수 있다는 장점이 있습니다.

const promise = new Promise((resolve, reject) => {
  // 비동기 작업 수행
  if (성공) {
    resolve('성공!');
  } else {
    reject('에러 ㅗㅗ ');
  }
});

📌 2. 프로미스의 3가지 상태

상태 설명
pending 대기 중( 비동기 작업이 아직 끝나지 않음)
fulfilled 이행됨 (비동기 작업 성공)
rejected 거부됨( 비동기 작업 실패)

 

즉 프로미스의 상태는 resolve 또는 reject 함수를 호출하는 것으로 결정된다.

 

비동기가 성공하면 ? pending-> fulfilled

성공 못하면? pending-> rejected

 

📌 2. 프로미스의 후속 처리 메서드

프로미스의 비동기 처리 상태가 변화하면 이에 따른 후속 처리를 해야하는데

이때 프로미스는 후속 메서드 then, catch, finally 를 제공한다.

 

 

 then()

성공했을 때 실행할 콜백을 등록

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

 

 catch()

실패했을 때 실행할 콜백을 등록.

promise
  .then(result => console.log(result))
  .catch(error => console.error(error));

 

 

🔁 finally()

성공/실패와 관계없이 항상 실행.

promise
  .then(result => console.log(result))
  .catch(error => console.error(error))
  .finally(() => console.log('작업 완료!'));

 

🔁 프로미스 체이닝

const url = 'https://jsonplaceholder.typicode.com';

// id가 1인 post의 UserId를 취득
promiseGet(`${url}/posts/1`)
  .then(({ userId }) => promiseGet(`${url}/users/${userId}`))
  .then(userInfo => console.log(userInfo))
  .catch(err => console.error(err));

 

  1. url 선언
    • API의 기본 URL인 jsonplaceholder url 변수에 저장. 이 URL을 활용하여 후속 요청을 보냄.
  2. 첫 번째 promiseGet(${url}/posts/1)
    • posts/1 API를 호출하여 id가 1인 게시물의 정보를 요청.
    • 이 요청은 프로미스를 반환하며, 응답이 성공적으로 오면 .then()이 실행됨.
  3. .then(({ userId }) => promiseGet(${url}/users/${userId}))
    • 첫 번째 API에서 받은 응답 객체에서 userId를 추출하여, 이를 사용해 두 번째 API (users/{userId})를 호출.
    • 이 요청도 프로미스를 반환하며, 그 결과를 다음 .then()에서 처리.
  4. .then(userInfo => console.log(userInfo))
    • 두 번째 API 요청에서 받은 사용자 정보를 콘솔에 출력. 여기서 userInfo는 사용자의 세부 정보.
  5. .catch(err => console.error(err))
    • 만약 어디에서든 에러가 발생하면 .catch()가 실행되고, 그 에러를 콘솔에 출력한다.

 

🔁 프로미스 정적 메서드

 

1️⃣ Promise.resolve()

Promise.resolve() 즉시 해결된 프로미스를 반환한다.

값을 전달하면 해당 값을 resolve한 프로미스를 반환하며, 값이 프로미스일 경우 그대로 그 프로미스를 반환.

const resolvedPromise = Promise.resolve(42);
resolvedPromise.then(value => console.log(value));  // 42

목적: 이미 값이 존재하거나, 동기 작업이 끝났을 때 이를 프로미스로 감싸서 비동기 흐름에 통합할 때 사용

 

 

2️⃣ Promise.reject()

Promise.reject() 즉시 거부된 프로미스를 반환한다.

에러를 전달하면 해당 에러를 reject한 프로미스를 반환한다.

const rejectedPromise = Promise.reject(new Error('Something went wrong'));
rejectedPromise.catch(error => console.error(error));  // Error: Something went wrong

 

 

목적: 에러를 바로 프로미스 형태로 반환하고, 비동기 흐름에서 에러를 처리할 때 유용함.

 

 

3️⃣ Promise.all()

Promise.all() 모든 프로미스가 이행(resolve)될 때까지 기다린 후, 모든 프로미스의 결과를 배열로 반환한다.

만약 하나라도 거부(reject)되면, 즉시 거부된 프로미스를 반환함.

const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);

Promise.all([p1, p2, p3])
  .then(values => console.log(values));  // [1, 2, 3]

 

 

목적: 여러 비동기 작업을 병렬로 실행하고, 모든 작업이 완료되면 그 결과를 모아서 처리할 때 유용

 

 

4️⃣ Promise.allSettled()

Promise.allSettled() 모든 프로미스가 완료되었을 때 (이행되었든 거부되었든) 그 결과를 배열로 반환한다.

각 프로미스는 { status: 'fulfilled', value: ... } 또는 { status: 'rejected', reason: ... } 형태로 결과를 받음.

const p1 = Promise.resolve(1);
const p2 = Promise.reject('error');
const p3 = Promise.resolve(3);

Promise.allSettled([p1, p2, p3])
  .then(results => console.log(results));  
// [
//   { status: 'fulfilled', value: 1 },
//   { status: 'rejected', reason: 'error' },
//   { status: 'fulfilled', value: 3 }
// ]

 

 

목적: 모든 프로미스가 완료될 때까지 기다리고, 그 상태(이행/거부)에 따른 처리가 필요할 때 사용

 

 

5️⃣ Promise.race()

Promise.race() 가장 먼저 이행(resolve)되거나 거부(reject)된 프로미스의 결과만 반환함.

즉, 여러 프로미스를 동시에 실행할 때, 첫 번째로 완료된 프로미스의 결과만을 받게 된다.

const p1 = new Promise(resolve => setTimeout(resolve, 100, 'one'));
const p2 = new Promise(resolve => setTimeout(resolve, 200, 'two'));

Promise.race([p1, p2])
  .then(result => console.log(result));  // "one"

 

목적: 여러 비동기 작업 중 가장 빠른 작업의 결과를 받고자 할 때 사용

 

 

다들 적재적소에 프로미스를 사용해서 사랑의 콜백지옥에 빠지지 않도록 하자구요~!