프로미스

ES6 Promise

자바스크립트는 비동기 처리 방법 중 하나로 콜백 함수를 사용하는 데, 가독성 측면에서 좋지 않고 예외 처리가 힘들다.

비동기식 처리 모델은 task를 병렬로 수행하기 때문에 task가 종료되지 않아도 다음 task를 수행한다. 이후 서버로부터 데이터가 응답되면 이벤트가 발생하게 되고 eventHandler가 데이터를 가지고 수행할 task를 계속 수행하게 된다.

DOM 이벤트, Timer 함수, Ajax 요청 등이 그 예이다.

하지만 병렬로 처리하기 때문에 블로킹이 되지 않아서 콜백 함수를 통해 순서를 보장하는데 그 과정에서 콜백함수가 중첩되어 callback Hell이 발생하게 된다.

비동기 처리 함수의 콜백 함수는 해당 이벤트가 발생하면 이벤트 큐로 이동한 후 호출스택이 비워졌을 때, 호출 스택으로 이동되어 실해된다.

setTimeout 함수의 콜백 함수는 이벤트 큐로 이동한 후에 호출 스택이 비워졌을 때 호출 스택으로 이동되어 실행되는데 이 때 setTimeout은 호출 스택에서 제거된 상태다. 결국 호출해봤자 말짱도루묵이라는 소리가 된다. (호출 스택이 비워져 아무리 함수를 호출해도 없어져 버린다.)

프로미스의 생성

Promise는 생성자 함수를 통해 인스턴스화 한다. resolve와 reject 함수를 인자로 전달받는다.

프로미스의 상태 정보는 fulfilled(비동기 처리 성공), rejected(비동기 처리 실패)가 있다.

또 후속 처리 메서드에는 then(두 개의 콜백 함수를 인자로 전달받아 성공, 실패 시 호출되도록 한다.), catch(예외처리, then 메서드의 에러가 발생하면 호출)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Promise example</title>
</head>
<body>
  <h1>Promise Example</h1>
  <pre id="result"></pre>
  <script>
  function get(url) {
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();

      xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.DONE) {
          if (xhr.status === 200) {
            resolve(xhr.response);
          } else {
            reject('Error' + xhr.status);
          }
        }
      };
      xhr.open('GET', url);
      xhr.send();
    });
  }
  const url = 'http://jsonplaceholder.typicode.com/posts';

  //  get(url).then(
  //    result => document.getElementById('result').innerHTML = result,
  //    error => console.log(error)
  //  );

  get(`${url}/1`)
  .then(result1 => get(`${url}?userID=${JSON.parse(result1).userID}`))
  // id가 1인 포스트 작성자의 아이디로 작성된 모든 포스트 검색
  .then(result2 => document.getElementById('result').innerHTML = result2)
  .catch(error => console.log(error));
  </script>
</body>
</html>

프로미스 체이닝

비동기 함수의 처리 결과에 따라 다른 비동기 함수를 호출해야 할 경우 중첩을 방지하고 후속 처리 메서드를 체이닝하여 여러 개의 프로미스를 연결할 수 있다.