프로미스 객체

김석·2023년 9월 5일
0

Javascript

목록 보기
2/3

1. 프로미스 객체

  • 비동기 작업의 최종 완료 또는 실패를 나타내는 객체
  • 프로미스 생성 시에는, resolve, reject 2개의 매개변수를 가진 콜백 함수를 인자로 넣게 됨.
  • resolve는 성공임을 알려주는 객체이고, reject는 실패임을 나태내는 오류 객체임.
const myPromise = new Promise((resolve, reject) => {
	// 비동기 작업 수행
    const data = fetch('서버로부터 요청할 URL');
    
    if(data)
    	resolve(data); // 만일 요청이 성공하여 데이터가 있다면
    else
    	reject("Error"); // 만일 요청이 실패하여 데이터가 없다면
})
  • 이렇게 만들어진 프로미스 객체는 비동기 작업이 완료된 이후 다음 작업을 연결시켜 진행할 수 있음.
  • .then()과 .catch() 함수가 있음.
  • 처리 성공으로 객체 내부에서 resolve(data)를 호출하면, 바로 .then()으로 이어져 성공에 대한 추가 처리 진행 가능.
  • 이 때 resolve()함수의 매개변수 값이 then 메서드의 함수 인자로 들어가게 되어, then 메서드 내부에서 프로미스 객체 내부에서 다룬 값을 사용할 수 있게 됨.
  • 반대로 처리 실패 시, reject도 동일한 로직으로 실행됨.
myPromise
    .then((value) => { // 성공적으로 수행했을 때 실행될 코드
    	console.log("Data: ", value); // 위에서 return resolve(data)의 data값이 출력된다
    })
    .catch((error) => { // 실패했을 때 실행될 코드
     	console.error(error); // 위에서 return reject("Error")의 "Error"가 출력된다
    })
    .finally(() => { // 성공하든 실패하든 무조건 실행될 코드
    	
    })

2. 프로미스 함수 등록

  • 보통 별도의 함수로 감싸서 사용하는 것이 일반적.
  • 함수에서 프로미스 객체르 리턴하는 방식.
// 프로미스 객체를 반환하는 함수 생성
function myPromise() {
  return new Promise((resolve, reject) => {
    if (/* 성공 조건 */) {
      resolve(/* 결과 값 */);
    } else {
      reject(/* 에러 값 */);
    }
  });
}

// 프로미스 객체를 반환하는 함수 사용
myPromise()
    .then((result) => {
      // 성공 시 실행할 콜백 함수
    })
    .catch((error) => {
      // 실패 시 실행할 콜백 함수
    });

이렇게 쓰는 이유는,
1. 재사용성: 필요할 때마다 함수를 호출하면 됨
2. 가독성: 코드 구조가 명확해져 비동기 작업 포함 코드 가동성을 높임
3. 확장성: 복잡한 비동기 로직도 구현 가능


3. 프로미스 상태

  1. Pending 상태
    대기 상태, 즉 처리 로직 완료되지 않은 상태
  2. Fulfilled 상태
    resolve()가 수행되어 비동기 처리 로직이 성공적으로 완료된 상태
  3. Rejected 상태
    reject()가 수행되어 비동기 처리 로직이 실패한 상태

4. 프로미스 핸들러

  1. .then()
    fulfilled 되었을 때 실행할 콜백 함수 등록하고, 새로운 프로미스를 반환함.
  2. .catch()
    rejected 되었을 때 실행할 콜백 함수를 등록하고, 새로운 프로미스를 반환함.
  3. finally()
    fulfilled/rejected 상관 없이 실행할 콜백 함수를 등록하고, 새로운 프로미스를 반환함

왜 값을 반환하지 않고 새로운 프로미스를 반환하는가?

  • 비동기 작업 완료 후 다른 작업들을 연속해서 체이닝할 수 있기 때문이라고 한다.
  • 왜 이게 좋은지, 값을 반환하도록 했을 때 안 되는 부분이 무엇인지 사실 아직 잘 모르겠다.

5. 프로미스 정적 메서드

  • 위의 예시처럼 생성자를 통해 생성하는 방법 외에 프로미스를 생성하는 방법

Promise.reslove()

// Promise.resolve() 를 사용하여 프로미스 객체를 반환하는 함수
function getPromiseNumber() {
  const num = getRandomNumber(); // 일반 값
  return Promise.resolve(num); // 프로미스 객체
}

// 핸들러를 이용하여 프로미스 객체의 값을 처리하는 함수
getPromiseNumber()
    .then((value) => {
      console.log(`랜덤 숫자: ${value}`);
    })
    .catch((error) => {
      console.error(error);
    });
  • 프로미스 객체와 전혀 연관 없는 함수 내에서 필요에 따라 프로미스 객체를 반환함
  • 프로미스의 장점을 활용하고 싶은 경우 유용함
  • 굳이 왜 쓰는지는 잘 모르겠다.

Promise.reject()

  • 위와 거의 동일하게 사용

Promise.all()

  • 굉장히 유용한 정적 메서드
  • 여러 개의 프로미스 요소들을 한꺼번에 비동기 작업으로 처리해야 할 때 사용
  • 모든 비동기 처리가 fulfilled될 때까지 기다리고, 모든 프로미스가 완료되면 then 핸들러가 실행됨
  • 여러 API 요청 보내고 모든 응답을 받아야 하는 경우 유용함.
// 1. 서버 요청 API 프로미스 객체 생성 (fetch)
const api_1 = fetch("https://jsonplaceholder.typicode.com/users");
const api_2 = fetch("https://jsonplaceholder.typicode.com/users");
const api_3 = fetch("https://jsonplaceholder.typicode.com/users");

// 2. 프로미스 객체들을 묶어 배열로 구성
const promises = [api_1, api_2, api_3];

// 3. Promise.all() 메서드 인자로 프로미스 배열을 넣어, 모든 프로미스가 이행될 때까지 기다리고, 결과값을 출력
Promise.all(promises)
    .then((results) => {
      // results는 이행된 프로미스들의 값들을 담은 배열.
      // results의 순서는 promises의 순서와 일치.
      console.log(results); // [users1, users2, users3]
    })
    .catch((error) => {
      // 어느 하나라도 프로미스가 거부되면 오류를 출력
      console.error(error);
    });

Promise.allSettled()

  • Promise.all()의 업그레이드 버전
  • 모든 프로미스의 각각 상태 값, 거부 사유를 모아놓은 배열 반환

Promise.any()

  • 주어진 모든 프로미스 중 하나라도 완료(fulfilled)되면 반환하는 정적 메서드

Promise.race()

  • 주어진 모든 프로미스 중 하나라도 처리되면(상태 여부 상관 x) 반환하는 정적 메서드

6. 콜백 함수 vs 프로미스

  • 콜백 함수는 복잡하기 않고 비교적 심플한 비동기 작업을 처리해야 할 때 사용하면 오히려 프로미스 방식보다 더 좋을 수 있음
  • 조금 복잡해지면 콜백 지옥에 빠져 가독성이 나쁜 코드가 만들어짐.
  • 따라서 비교적 복잡한 비동기 작업을 처리할 때는 Promise 객체를 사용하면 코드를 보다 간결하게 작성할 수 있음
  • 하지만 콜백 지옥처럼 프로미스 지옥(then, catch 난무한 코드)에 빠질 수 있음

이를 해결해주는 것: async, await


출처

https://inpa.tistory.com/entry/%F0%9F%8C%90-js-async
https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%B2%98%EB%A6%AC-Promise

profile
handsome

0개의 댓글