Promise 함수

MyeonghoonNam·2021년 2월 9일
0

Promise 함수에 대해 이해하자.


Promise

  • 콜백 함수를 어느 정도 개선할 수 있는 동기적으로 보이는 비동기 처리 방식
  • Promise로 정의된 작업끼리는 연결할 수 있으며, 이를 통해 코드의 depth가 크게 증가하지 않는 효과가 있다.

Promise의 상태

  • pending : 로직이 수행중인 상태를 말한다.

  • fulfilled : 로직이 성공적으로 이루어진 상태를 말한다.

  • rejected : 로직이 어떤 이유에 의해 실패로 이루어진 상태를 말한다.


Promise 생성

Promise 객체의 인자로는 Executor라는 콜백함수가 들어가는 데 이 함수는 resolvereject라는 두 개의 함수를 매개변수로 받는 함수이다.

Executor는 비동기 작업을 시작하고 모든 작업을 끝낸다. 여기서 성공적으로 작업이 이행된다면 resolve함수를 호출하고, 도중에 오류가 발생한 경우 reject함수를 호출한다.

const promise = new Promise((resolve, reject) => {
    console.log('doing something...');
    setTimeout(() => {
      // Promise가 성공적으로 이루어졌을 경우 resolve를 리턴한다.
      resolve('hoon')

      // Promise가 실패적으로 이루어졌을 경우 reject를 리턴한다.
      // reject(new Error('not found'));
    }, 2000)
  })

Promise 실행 및 예외처리

  • then : promise 성공시 호출할 함수들을 나열한다.
  • catch : promise 실패시 호출할 함수들을 나열한다.
  • finally : promise 성공과 실패에 관계없이 항상 호출되는 함수들을 나열한다.
promise
    .then(value => {
      console.log(value);
    })
    .catch(error => {
      console.log(error);
    })
    .finally(() => {
      console.log('finally');
    });

Promise Chaining

then 메소드는 promise 객체를 리턴하고 인수로 받은 콜백 함수들의 리턴 값(resolve)을 이어받는다. 그러므로 아래와 같이 promise의 연결이 가능하다.

const fetchNumber = new Promise((resolve, reject) => {
  setTimeout(() => resolve(1), 1000);
})

fetchNumber
  .then(num => num * 2)
  .then(num => num * 3)
  .then(num => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(num - 1)
      }, 1000);
    })
  })
  .then(num => console.log(num)); // 출력값 = 5

Promise 내장 함수들

Promise.all(iterable)

여러 프로미스를 동시에 처리할 때 유용하다.

const delay = (time) => new Promise((resolve) => setTimeout(resolve, time));

const promise1 = delay(3000);
const promise2 = delay(4000);
const promise3 = delay(5000);

Promise.all([promise1, promise2, promise3]).then(() => {
  console.log('work Done !');
});

Promise.race(iterable)

여러 프로미스중에 하나라도 resolve or reject 되면 종료된다.

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);

  return Math.floor(Math.random() * (max - min)) + min;
}

const promise = [1, 2, 3, 4, 5].map((n) => {
  const delayTime = getRandomInt(1000, 5000);

  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(`${n}번 고양이 완주 !`);
      resolve(`${n}번 고양이 승리 !`);
    }, delayTime);
  });
});

Promise.race(promise).then((message) => console.log(message));

Promise.any

race와 달리 여러 프로미스중에 reject는 무시하고 resolve된 프로미스가 하나라도 존재하면 종료한다.

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);

  return Math.floor(Math.random() * (max - min)) + min;
}

const promise = [1, 2, 3, 4, 5].map((n) => {
  const delayTime = getRandomInt(1000, 5000);

  return new Promise((resolve, reject) => {
    if (n === 1) {
      return reject(`${n}번 고양이 기권 !`);
    }

    setTimeout(() => {
      console.log(`${n}번 고양이 완주 !`);
      resolve(`${n}번 고양이 승리 !`);
    }, delayTime);
  });
});

// node js에서는 아직 지원되지 않는다.
Promise.any(promise).then((message) => console.log(message));

Promise.allSettled(iterable)

여러 프로미스들이 성공했거나 실패했거나 상관없이 모두 이행된 경우를 처리하며 각 프로미스 상태에 대해 반한한다.

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);

  return Math.floor(Math.random() * (max - min)) + min;
}

const promise = [1, 2, 3, 4, 5].map((n) => {
  const delayTime = getRandomInt(1000, 5000);

  return new Promise((resolve, reject) => {
    if (n % 2 === 0) {
      return reject(`${n}번 고양이 완주 실패 ㅠ ㅠ!`);
    }

    setTimeout(() => {
      resolve(`${n}번 고양이 승리 !`);
    }, delayTime);
  });
});

Promise.allSettled(promise).then((result) => console.log(result));
profile
꾸준히 성장하는 개발자를 목표로 합니다.

0개의 댓글