Skip to content

Latest commit

Β 

History

History
123 lines (97 loc) Β· 6.3 KB

Promise.md

File metadata and controls

123 lines (97 loc) Β· 6.3 KB

ES6문법 - Promise

written by sohyeon, hyemin πŸ’‘


1. Promiseλž€?

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 비동기 처리λ₯Ό μœ„ν•œ ν•˜λ‚˜μ˜ νŒ¨ν„΄μœΌλ‘œ μ½œλ°±ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€. ν•˜μ§€λ§Œ 전톡적인 콜백 νŒ¨ν„΄μ€ 가독성이 λ‚˜μ˜κ³  비동기 처리 쀑 λ°œμƒν•œ μ—λŸ¬μ˜ μ˜ˆμ™Έ μ²˜λ¦¬κ°€ κ³€λž€ν•˜λ©° μ—¬λŸ¬κ°œμ˜ 비동기 처리 λ‘œμ§μ„ ν•œκΊΌλ²ˆμ— μ²˜λ¦¬ν•˜λŠ” 것도 ν•œκ³„κ°€ μžˆλ‹€.
ES6μ—μ„œ 비동기 처리λ₯Ό μœ„ν•œ 또 λ‹€λ₯Έ νŒ¨ν„΄μœΌλ‘œ ν”„λ‘œλ―ΈμŠ€(Promise)λ₯Ό λ„μž…ν–ˆλ‹€. 콜백 νŒ¨ν„΄μ΄ 가진 단점을 λ³΄μ™„ν•˜λ©° 비동기 처리 μ‹œμ μ„ λͺ…ν™•ν•˜κ²Œ ν‘œν˜„ν•œλ‹€.

2. 생성

ν”„λ‘œλ―ΈμŠ€λŠ” μƒμ„±μž ν•¨μˆ˜λ₯Ό 톡해 μΈμŠ€ν„΄μŠ€ν™” ν•œλ‹€.
Promise μƒμ„±μž ν•¨μˆ˜λŠ” 비동기 μž‘μ—…μ„ μˆ˜ν–‰ν•  콜백 ν•¨μˆ˜λ₯Ό 인자둜 μ „λ‹¬λ°›λŠ”λ°
이 콜백 ν•¨μˆ˜λŠ” resolve와 reject ν•¨μˆ˜λ₯Ό 인자둜 전달 λ°›λŠ”λ‹€.

// Promise 객체의 생성
const promise = new Promise((resolve, reject) => {
  // 비동기 μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€.

  if (/* 비동기 μž‘μ—… μˆ˜ν–‰ 성곡 */) {
    resolve('result');
  }
  else { /* 비동기 μž‘μ—… μˆ˜ν–‰ μ‹€νŒ¨ */
    reject('failure reason');
  }
}

PromiseλŠ” 비동기 μ²˜λ¦¬κ°€ 성곡(fulfilled)ν•˜μ˜€λŠ”μ§€ λ˜λŠ” μ‹€νŒ¨(rejected)ν•˜μ˜€λŠ”μ§€ λ“±μ˜ μƒνƒœ(state) 정보λ₯Ό κ°–λŠ”λ‹€.

Promise μƒμ„±μž ν•¨μˆ˜κ°€ 인자둜 전달받은 콜백 ν•¨μˆ˜λŠ” λ‚΄λΆ€μ—μ„œ 비동기 처리 μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€.
μ΄λ•Œ 비동기 μ²˜λ¦¬κ°€ μ„±κ³΅ν•˜λ©΄ 콜백 ν•¨μˆ˜μ˜ 인자둜 전달받은 resolve ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.
μ΄λ•Œ ν”„λ‘œλ―ΈμŠ€λŠ” fulfilled(비동기 처리 μˆ˜ν–‰ 성곡) μƒνƒœκ°€ λœλ‹€.
비동기 μ²˜λ¦¬κ°€ μ‹€νŒ¨ν•˜λ©΄ reject ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€. μ΄λ•Œ ν”„λ‘œλ―ΈμŠ€λŠ” rejected(비동기 처리 μˆ˜ν–‰ μ‹€νŒ¨) μƒνƒœκ°€ λœλ‹€.

2-1. μ˜ˆμ‹œ

const promiseAjax = (method, url, payload) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.setRequestHeader('Content-type', 'application/json');
    xhr.send(JSON.stringify(payload));

    xhr.onreadystatechange = function () {
      // μ„œλ²„ 응닡 μ™„λ£Œκ°€ μ•„λ‹ˆλ©΄ λ¬΄μ‹œ
      if (xhr.readyState !== XMLHttpRequest.DONE) return;

      if (xhr.status >= 200 && xhr.status < 400) {
        // resolve λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄μ„œ 처리 κ²°κ³Όλ₯Ό 전달
        resolve(xhr.response); // Success!
      } else {
        // reject λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄μ„œ μ—λŸ¬ λ©”μ‹œμ§€λ₯Ό 전달
        reject(new Error(xhr.status)); // Failed...
      }
    };
  });
};

μœ„ 예제처럼 비동기 ν•¨μˆ˜ λ‚΄μ—μ„œ Promise 객체λ₯Ό μƒμ„±ν•˜κ³  κ·Έ λ‚΄λΆ€μ—μ„œ 비동기 처리λ₯Ό κ΅¬ν˜„ν•œλ‹€. μ΄λ•Œ 비동기 μ²˜λ¦¬μ— μ„±κ³΅ν•˜λ©΄ resolve λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€. μ΄λ•Œ resolve λ©”μ†Œλ“œμ˜ 인자둜 비동기 처리 κ²°κ³Όλ₯Ό μ „λ‹¬ν•œλ‹€. 이 처리 κ²°κ³ΌλŠ” Promise 객체의 후속 처리 λ©”μ†Œλ“œλ‘œ μ „λ‹¬λœλ‹€.
λ§Œμ•½ 비동기 μ²˜λ¦¬μ— μ‹€νŒ¨ν•˜λ©΄ reject λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€. μ΄λ•Œ reject λ©”μ†Œλ“œμ˜ 인자둜 μ—λŸ¬ λ©”μ‹œμ§€λ₯Ό μ „λ‹¬ν•œλ‹€. 이 μ—λŸ¬ λ©”μ‹œμ§€λŠ” Promise 객체의 후속 처리 λ©”μ†Œλ“œλ‘œ μ „λ‹¬λœλ‹€.

3. 후속 처리 λ©”μ†Œλ“œ

Promise둜 κ΅¬ν˜„λœ 비동기 ν•¨μˆ˜λŠ” Promise 객체λ₯Ό λ°˜ν™˜ν•˜μ—¬μ•Ό ν•œλ‹€. Promise둜 κ΅¬ν˜„λœ 비동기 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” μΈ‘(promise consumer)μ—μ„œλŠ” Promise 객체의 후속 처리 λ©”μ†Œλ“œ(then, catch)λ₯Ό 톡해 비동기 처리 κ²°κ³Ό λ˜λŠ” μ—λŸ¬ λ©”μ‹œμ§€λ₯Ό 전달받아 μ²˜λ¦¬ν•œλ‹€. Promise κ°μ²΄λŠ” μƒνƒœλ₯Ό κ°–λŠ”λ‹€κ³  ν•˜μ˜€λ‹€. 이 μƒνƒœμ— 따라 후속 처리 λ©”μ†Œλ“œλ₯Ό 체이닝 λ°©μ‹μœΌλ‘œ ν˜ΈμΆœν•œλ‹€. Promise의 후속 처리 λ©”μ†Œλ“œλŠ” μ•„λž˜μ™€ κ°™λ‹€.

  • then λ©”μ†Œλ“œ
    두 개의 콜백 ν•¨μˆ˜λ₯Ό 인자둜 전달 λ°›λŠ”λ‹€.
    첫 번째 콜백 ν•¨μˆ˜λŠ” 성곡(fulfilled, resolve ν•¨μˆ˜κ°€ 호좜된 μƒνƒœ) μ‹œ 호좜되고
    두 번째 ν•¨μˆ˜λŠ” μ‹€νŒ¨(rejected, reject ν•¨μˆ˜κ°€ 호좜된 μƒνƒœ) μ‹œ ν˜ΈμΆœλœλ‹€.
    then λ©”μ†Œλ“œλŠ” Promiseλ₯Ό λ°˜ν™˜ν•œλ‹€.

  • catch λ©”μ†Œλ“œ
    μ˜ˆμ™Έ(비동기 μ²˜λ¦¬μ—μ„œ λ°œμƒν•œ μ—λŸ¬μ™€ then λ©”μ†Œλ“œμ—μ„œ λ°œμƒν•œ μ—λŸ¬)κ°€ λ°œμƒν•˜λ©΄ ν˜ΈμΆœλœλ‹€.
    catch λ©”μ†Œλ“œλŠ” Promiseλ₯Ό λ°˜ν™˜ν•œλ‹€.

3-1. μ˜ˆμ‹œ

/*
    비동기 ν•¨μˆ˜ promiseAjax은 Promise 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.
    Promise 객체의 후속 λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 비동기 처리 결과에 λŒ€ν•œ 후속 처리λ₯Ό μˆ˜ν–‰ν•œλ‹€.
*/
promiseAjax('GET', 'http://jsonplaceholder.typicode.com/posts/1')
  .then(JSON.parse)
  .then(
  // 첫 번째 콜백 ν•¨μˆ˜λŠ” 성곡(fulfilled, resolve ν•¨μˆ˜κ°€ 호좜된 μƒνƒœ) μ‹œ ν˜ΈμΆœλœλ‹€.
  render,
  // 두 번째 ν•¨μˆ˜λŠ” μ‹€νŒ¨(rejected, reject ν•¨μˆ˜κ°€ 호좜된 μƒνƒœ) μ‹œ ν˜ΈμΆœλœλ‹€.
  console.error
);

4. μ—λŸ¬ 처리

비동기 처리 μ‹œ λ°œμƒν•œ μ—λŸ¬ λ©”μ‹œμ§€λŠ” then λ©”μ†Œλ“œμ˜ 두 번째 콜백 ν•¨μˆ˜λ‘œ μ „λ‹¬λœλ‹€.
Promise 객체의 후속 처리 λ©”μ†Œλ“œ catchλ₯Ό μ‚¬μš©ν•΄λ„ μ—λŸ¬λ₯Ό μ²˜λ¦¬ν•  수 μžˆλ‹€.

예제

promiseAjax('GET', 'http://jsonplaceholder.typicode.com/posts/1')
  .then(JSON.parse)
  .then(render)
  .catch(console.error);

then λ©”μ†Œλ“œμ˜ 두 번째 콜백 ν•¨μˆ˜λŠ” 비동기 μ²˜λ¦¬μ—μ„œ λ°œμƒν•œ μ—λŸ¬(reject ν•¨μˆ˜κ°€ 호좜된 μƒνƒœ)λ§Œμ„ μΊμΉ˜ν•œλ‹€.
ν•˜μ§€λ§Œ catch λ©”μ†Œλ“œλŠ” 비동기 μ²˜λ¦¬μ—μ„œ λ°œμƒν•œ μ—λŸ¬(reject ν•¨μˆ˜κ°€ 호좜된 μƒνƒœ)뿐만 μ•„λ‹ˆλΌ then λ©”μ†Œλ“œ λ‚΄λΆ€μ—μ„œ λ°œμƒν•œ μ—λŸ¬λ„ μΊμΉ˜ν•œλ‹€.
λ”°λΌμ„œ μ—λŸ¬ μ²˜λ¦¬λŠ” catch λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 편이 보닀 νš¨μœ¨μ μ΄λ‹€.

5. ν”„λ‘œλ―ΈμŠ€ 체이닝

비동기 ν•¨μˆ˜μ˜ 처리 κ²°κ³Όλ₯Ό 가지고 λ‹€λ₯Έ 비동기 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•˜λŠ” 경우,
ν•¨μˆ˜μ˜ 호좜이 쀑첩(nesting)이 λ˜μ–΄ λ³΅μž‘λ„κ°€ λ†’μ•„μ§€λŠ” 콜백 헬이 λ°œμƒν•œλ‹€. ν”„λ‘œλ―ΈμŠ€λŠ” 후속 처리 λ©”μ†Œλ“œλ₯Ό 체이닝(chainning)ν•˜μ—¬ μ—¬λŸ¬ 개의 ν”„λ‘œλ―ΈμŠ€λ₯Ό μ—°κ²°ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ‹€. 이둜써 콜백 헬을 ν•΄κ²°ν•œλ‹€.

Promise 객체λ₯Ό λ°˜ν™˜ν•œ 비동기 ν•¨μˆ˜λŠ” ν”„λ‘œλ―ΈμŠ€ 후속 처리 λ©”μ†Œλ“œμΈ thenμ΄λ‚˜ catch λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.
λ”°λΌμ„œ then λ©”μ†Œλ“œκ°€ Promise 객체λ₯Ό λ°˜ν™˜ν•˜λ„λ‘ ν•˜λ©΄(then λ©”μ†Œλ“œλŠ” 기본적으둜 Promiseλ₯Ό λ°˜ν™˜ν•œλ‹€.) μ—¬λŸ¬ 개의 ν”„λ‘œλ―ΈμŠ€λ₯Ό μ—°κ²°ν•΄ μ‚¬μš©ν•  수 μžˆλ‹€.


Reference & Additional Resources