[JS] 자바스크립트 프로미스(Promise)

younoah·2021년 1월 20일
0

[JavaScript]

목록 보기
14/15

Promise

프로미스는 자바스크립트의 객체이고 비동기적인 처리(수행)를 할 때 사용한다.

비동기적인 처리란, 특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 것을 말한다.


중요 포인트

  1. state
  • pending : 비동기 처리를 수행하고 있는 상태
  • fulfiled : 비동기 처리를 성공적으로 완료하고 프로미스가 결과 값을 반환해준 상태
  • rejected : 비동기 처리가 수행중에 에러가 발생하여 완료하지 못한 상태 (e.g. 파일찾기실패, 네트워크 문제)

  1. Producer vs Comsumer의 차이점 이해

Promise는 크게 2가지 파트로 나뉜다.

  • Producer : 비동기 처리를 수행해서 해당하는 데이터를 만들어 낸다. (

프로미스를 생성하고 정의할 때 resolve, reject 를 사용하여 비동기 처리를 하고 결과를 반환한다.


  • Comsumer : 비동기 처리 결과를 받아 온다.

resolve, reject 의 결과 에따라 케이스별로 then, catch, finally 를 사용하여 비동기 처리 이후의 기능을 처리한다.

쉽게 말해 Producer( resolve, reject) 로 비동기적인 처리를 하고 결과에 따라 Comsumer(then, catch, finally) 로 케이스를 나누어 비동기 이후의 기능을 수행한다.


Promise 만들기


1. Producer

프로미스는 excutor라는 콜백함수를 전달해야한다. excutor라는 콜백함수에는 또 다른 2가지의 콜백함수를 인자에 전달하고 사용한다.

  • resolve : 비동기 처리를 정상적으로 수행을 완료했을 때 호출하는 함수이다. fulfiled상태가 되고 최종 데이터를 Comsumer의 then 에게 전달한다.

  • reject : 비동기 처리를 수행하다가 중간에 문제가 생기면 호출하는 함수이다. rejected 상태가 되고 에러를 Comsumer의 catch 에게 전달한다.

프로미스에서 resolvereject를 사용하지 않으면 해당 프로미스는 pending 상태로 남아있는다. 따라서 올바르게 프로미스를 완료하려면 resolvereject를 사용해야한다.

프로미스가 수행이 성공적으로 됬을때는 resolve 콜백함수를

프로미스가 수행이 실패했을 때는 reject 콜백함수를 사용한다.


프로미스의 Producer 선언

const input = prompt('비밀번호를 입력해주세요: ');

const promise = new Promise((resolve, reject) => {
  console.log('doing something...');
  setTimeout(() => {
    if (input === '1234') {
      // 수행이 성공적으로 됬을때는 resolve
      resolve('alice');
    } else {
      // 수행이 실패했을 때는 reject
      reject(new Error('비밀번호가 틀렸습니다.'));
    }
  }, 2000);
});

❗️주의❗️

new Promise((resolve, reject) => {...});

이렇게 프로미스를 만드는 순간 excutor라는 콜백함수가 그 즉시 바로 실행이 된다.

만약 네트워크 요청을 사용자가 요청했을 때만 네트워크 통신을 하게 하려할 때 이점을 유의 해서 코드를 작성해야 한다.


2. Comsumer

Producer의 처리결과(resolve, reject) 따라 기능을 정의한다.

  • then : resolve 가 호출된 이후에 값을 전달받아서 호출이 된다. 비동기 처리가 성공적으로 끝났을때 이후 동작을 작성한다.
  • catch : reject 가 호출된 이후에 값을 전달받아서 호출이 된다. 비동기 처리가 실패해서 에러처리를 할때 사용한다.
  • finally : 비동기 처리가 성공하든 실패하든 무조건 호출이 된다.

then, catch, finally 모두 리턴값이 프로미스이기 때문에 체이닝이 가능하다.

promise
  .then(name => console.log(`${name}님 반갑습니다.`))
  .catch(error => console.log(error))
  .finally(() => console.log('finally'));
promise
  .then(name => console.log(`${name}님 반갑습니다.`))
  .catch(console.log) // 인자를 생략하고 함수의 정의만 입력해서 받안온 값을 곧바로 다른 함수로 전달해서 실행할 수 있다.
  .finally(() => console.log('finally'));

예제 완성 코드

const input = prompt('비밀번호를 입력해주세요: ');

// Producer
const promise = new Promise((resolve, reject) => {
  console.log('비동기 처리 시작');
  setTimeout(() => {
    if (input === '1234') {
      // 수행이 성공적으로 됬을때는 resolve
      resolve('alice');
    } else {
      // 수행이 실패했을 때는 reject
      reject(new Error('비밀번호가 틀렸습니다.'));
    }
  }, 2000);
});

console.log('중간에 다른 처리작업1');
console.log('중간에 다른 처리작업2');

// consumer
promise
  .then(name => console.log(`${name}님 반갑습니다.`))
  .catch(console.log)
  .finally(() => console.log('finally'));

// 실행결과
// 비동기 처리시작
// 중간에 다른 작업1
// 중간에 다른 작업2
// alice님 반갑습니다.
// finally

profile
console.log(noah(🍕 , 🍺)); // true

0개의 댓글