Promise

Promise는 비동기 조작의 최종 완료(Resolve) 또는 실패(Reject)를 나타내는 객체입니다. 그리고 Fetch API를 이용하면 요청(Request), 응답(Resposne)와 같은 HTTP의 파이프라인을 구성하는 요소를 조작하는것이 가능합니다.

영상 강의

PART 1

PART 2



예제

Promise는 다음과 같이 수평적인 코드(콜백 지옥)의 형태를 바꿀 수 있게 해줍니다.

func1(function (value1) {
  func2(value1, function (value2) {
    func3(value2, function (value3) {
      func4(value3, function (value4) {
        func5(value4, function (value5) {
          // ...
        });
      });
    });
  });
});

이를 수직적인 코드로 변경하면 보다 깔끔하고 읽기 쉬운 코드를 작성할 수 있습니다.

func1(value1)
  .then(func2)
  .then(func3)
  .then(func4)
  .then(func5, value5 => {
    // ...
  });

ES6 등장 이전엔 bluebird, Q와 같은 라이브러리를 사용했습니다.

const Promise = require('bluebird');

const func1 = () => {
  return new Promise((resolve, reject) => {
    // ...
  });
}

func1
  .then(func2)
  .then(func3)
  .then(func4)
  .then(func5, value5 => {
    // ...
  });

ES6+ 부터는 기본 제공되는 Promise를 사용할 수 있습니다. Promise가 제대로 동작(fulfill)했을 때 호출되는 resolve 메소드와 Promise가 제대로 동작하지 않았을 때(rejected) 호출되는 reject 메소드를 이용해 Promise를 다룰 수 있습니다.

Promise

const promise = new Promise((resolve, reject) => {
  if ( true ) {
    resolve();
  } else {
    reject();
  }
});

promise
  .then(() => {
    // ...
  })
  .catch(error => {
    console.error(error.message);
  })

Promise.all()

비동기 처리가 요구되는 API 배열에 Promise의 .all()을 사용하면 Promise를 병렬 처리 할 수 있습니다.

let api = [
  '/api/commits',
  '/api/issues/opened',
  '/api/issues/completed',
  '/api/pullrequests'
];

let promises = api.map(url => {
  return new Promise((resolve, reject) => {
    $.ajax({ url }).done(data => resolve(data));
  });
});

Promise
  .all(promises)
  .then(results => console.log(results));

Promise.race()

Promise의 .race() 메서드를 사용하면 전달된 Promise 중 먼저 도착한 것을 실행(resolve) 합니다.

let lacingApis = [
  '/api/race/products',
  '/api/race/photos',
];

const lacings = lacingApis.map((url, index) => {
  let delay = Math.floor(Math.random() * 1000);
  return new Promise((resolve, reject) => {
    window.setTimeout(() => resolve(url), delay);
  });
});

Promise
  .race(lacings)
  .then(result => console.log(result));

참고