About Promise

손병진·2020년 12월 9일
0

Promise

  • 기본 개념
    자바스크립트의 내장 객체로써, 정해진 장시간의 기능을 수행하고 나서 정상적으로 완료됐다면 성공의 메시지와 함께 처리된 결과값을 전달해주고, 만약 기능을 수행하다가 예상치 못한 문제가 발생했다면 에러를 전달한다.

  • 언제 사용하는가
    주로 비동기!!! 적인 작업을 수행할 때, 특히 무거운 프로세스(네트워크에서 데이터를 받아오거나 파일을 읽는 작업)에서 활용된다. 그리고 비동기 처리에서 활용되는 콜백함수를 대신하여 사용할 수 있다.

  • promise 개념의 중요한 두가지 포인트

    1. state
      - 정해진 프로세스가 진행 중인지, 성공했는지, 실패했는지에 대하여
      - pending 작업이 진행 중일 때
      - fulfilled 성공
      - rejected 실패

    2. producer, consumer 차이
      데이터를 제공하는 부분과 소비하는 부분을 구분해야한다.
      • producer
        원하는 기능을 수행해서 데이터를 만드는 작업
      • consumer
        데이터를 받아 활용하는 작업

Producer

const promise = new Promise((resolve, reject)=>{
  console.log('doing something..');
  setTimeout(()=>{
    resolve('son')
  },5000)
})
/* 
Promise 생성자는 executor 콜백함수를 받는데
executor는 또다시 두가지의 콜백함수를 받는다.
기능을 정상적으로 수행해서 마지막에 최종적으로 전달하는 resolve
기능을 수행하다가 중간에 문제가 생기면 호출하는 reject
*/
  • 보통 promise 안에서 무거운 작업들을 하기 마련이다.
    왜냐하면, 네트워크에서 어떤 데이터를 받아오는 과정은 시간이 꽤 소요된다. 그런 작업을 동기적으로 처리하면 데이터를 받아오는 동안 다음 라인의 코드가 실행되지 않기 때문에 무거운 작업은 비동기적으로 처리하는 것이 좋다. 그렇기에 네트워크 통신이나 파일을 읽어오는 작업은 비동기적으로 처리하는 것이 좋다.
  • 새로운 프로미스 인스턴스를 만드는 순간 executor 콜백함수가 바로 실행된다(유의점).

Consumer

  • producer에서 전달하는 데이터를 가지고 then, catch, finally 를 이용해서 값을 받아올 수 있다.
// 위 코드와 이어져 있어야 한다.
promise
  .then((value) => {
  console.log(value);
  /* resolve 받아오면 그대로 실행하고
  reject 받아오면 에러(에러 이름을 명시)가 발생한다.*/
})
  .catch(error=>{
    console.log(error) // 에러일때 해당 코드를 실행
  })
  /*코드 구조에 대한 설명
  .then 뒤에 어떻게 .catch 를 바로 쓸 수 있냐면
  then을 실행하면 리턴값으로 다시 promise가 나오기 때문에 이어서 .catch 구문을 사용할 수 있다.
  */
  .finally(()=>{
    console.log('byungjin') // 성공, 실패 상관없이 무조건 맨마지막에 실행됨
  })

promise chaining

  • 프로미스에 대하여 여러 consumer가 중첩적으로 실행되는 구조를 의미한다.
const fetchNumber = new Promise((resolve, reject) => {
  console.log('loading');
  setTimeout(() => {
    resolve(1);
  }, 1000);
});

fetchNumber
  .then((num) => num + 1)
  .then((num) => {
    // 비동기 안에 비동기가 있는 경우 리턴값으로 promise를 전달할 수도 있다.
    return Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(num * 2);
      }, 1000);
    });
  })
  .then((num) => {
    console.log(num);
  });

Error Handling

  • 먼저 프로미스를 리턴하는 함수가 중첩되어 사용되는 예시를 들 수 있다.
const first = () =>
  new Promise((resolve, reject) => {
    setTimeout(resolve('손'), 1000);
  });

const second = (first) =>
  new Promise((resolve, reject) => {
    setTimeout(resolve(`${first}`), 1000);
  });

const last = (second) =>
  new Promise((resolve, reject) => {
    setTimeout(resolve(`${second}`), 1000);
  });

// 프로미스 체인
first() //
  .then(second) // 받아오는 인자와 넘겨주는 인자가 같다면 생략가능하다.
  .then(last)
  .then(console.log);// '손 병 진' 이라는 값을 출력 
  • 만약 위 프로미스 체이닝에서 오류를 다루고 싶다면?!
const first = () =>
  new Promise((resolve, reject) => {
    setTimeout(resolve('손'), 1000);
  });

const second = (first) =>
  new Promise((resolve, reject) => {
    setTimeout(reject(`${first}`), 1000); // resolve 를 reject 로 변경
  });

const last = (second) =>
  new Promise((resolve, reject) => {
    setTimeout(resolve(`${second}`), 1000);
  });

// .catch 구문을 활용하여 잡아주거나 에러시 발생할 코드를 설정해준다.
first() //
  .then(second)
  .catch((error) => {
    return '후';
  })
  .then(last)
  .then(console.log); // '후 진' 출력
profile
https://castie.tistory.com

0개의 댓글