Home 프로미스 Promise
Post
X

프로미스 Promise

Javascript에서의 Promise에 대해 알아보자.


Promise

Javascript에서 비동기 처리를 위해 콜백 페턴을 많이 사용합니다.

콜백 패턴은 코드가 길어짐에따라 콜백지옥 현상이 쉽게 나타나 가독성이 나쁘고 비동기 처리 중 발생하는 에러 처리가 힘든 문제점이 있습니다.

이러한 단점을 보안 하기 위해 ES6에서는 새로우 패턴인 Promise를 도입했습니다.

Promise는 콜백 패턴의 단점을 보완하고 비동기 처리 시점을 명확히 할 수 있다는 장점이 있습니다.


Promise의 생성

Promise는 Promise 생성자 함수를 통해 인스턴스화합니다.

Promise 생성자 함수는 비동기 작업을 수행할 콜백 함수를 인자로 받습니다.

해당 콜백 함수는 resolve, reject 함수를 인자로 받습니다.

1
2
3
4
5
6
7
8
9
10
11
  // Promise 객체의 생성
  const promise = new Promise((resolve, reject) => {
    // 비동기 작업을 수행한다.

    if (/* 비동기 작업 수행 성공 */) {
      resolve('result');
    }
    else { /* 비동기 작업 수행 실패 */
      reject('fail reason');
    }
  });

Promise는 비동기 처리의 성공 실패에 따라 resolve 함수, reject 함수를 호출하게 됩니다.

이 때, Promise는 성공, 실패에 따라 상태 정보를 갖게 됩니다.

  • Promise의 상태정보

    상태의미구현
    pending비동기 수행 전resolve 또는 reject 함수 호출 전 상태
    fulfilled비동기 성공resolve 함수가 호출된 상태
    rejected비동기 실패reject 함수가 호출된 상태
    settled비동기 완료resolve 또는 reject 함수가 호출된 상태

Promise의 후속 처리 method

Promise 객체의 후속 처리 Method (then, catch)를 총해 비동기 처리 결과, 에러 메세지를 전달 받아 처리합니다.

  • then 메서드

    • then 메서드는 2개의 callback 함수를 인자로 전달 받습니다.
    • 첫 번째 인자는 성공 시 실행됩니다. ( 즉, fulfilled 상태, resolve 함수가 호출된 경우)
    • 두 번쨰 인자는 실패 시 실행됩니다. ( 즉, rejected 상태, reject 함수가 호출된 경우)
  • catch 메서드

    • catch 메서드는 비동기 처리와 then 메서드 실행 중 예외 발생 시 호출됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const promise = new Promise((resolve, reject) => {
  // 실제로는 여기서 XHR이나 HTML5 API를 사용할 것입니다.
  setTimeout(() => {
    resolve("success");
    // reject(new Error("network error")); 비동기 처리 실패 시
  }, 2000);
});
promise
  .then((val) => {
    console.log(val);
  })
  .catch((error) => {
    console.lot(error);
  });

Promise의 에러 처리

Promise를 이용한 에러 처리 방법은 2가지가 있습니다.

  • then 메서드의 두 번째 인자

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    const promise = () => {
      return new Promise((resolve, reject) => {
        let a = 1;
    
        if (a == 3) {
          resolve("success");
        } else {
          reject("failed");
        }
      });
    };
    
    promise().then(
      (message) => {
        console.log("This is in the then " + message);
      },
      (error) => {
        console.log("This is in the then " + error);
      }
    );
    
  • catch 메서드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    const promise = () => {
      return new Promise((resolve, reject) => {
        let a = 1;
    
        if (a == 3) {
          resolve("success");
        } else {
          reject("failed");
        }
      });
    };
    
    promise()
      .then((message) => {
        console.log("This is in the then " + message);
      })
      .catch((error) => {
        console.log("This is in the then " + error);
      });
    

catch 메서드를 사용하는 이유

catch 메서드를 모든 then 메서드를 호출한 이후에 호출하면 비동기 처리에서 발생한 에러(reject 상태)뿐만 아니라 then 메서드 내부에서 발생한 에러까지 처리할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const promise = () => {
  return new Promise((resolve, reject) => {
    let a = 1;

    if (a == 1) {
      resolve("success");
    } else {
      reject("failed");
    }
  });
};

promise()
  .then((message) => {
    console.xxx("This is in the then " + message);
  })
  .catch((error) => {
    console.log(error);
  });
1
  TypeError: console.xxx is not a function

Promise 체이닝 (Chaining)

Promise는 후속 처리 메서드를 체이닝(chaining)하여 여러 개의 프로미스를 연결하여 사용할 수 있습니다.

Promise 객체를 반환하는 비동기 함수는 then, catch 메서드를 사용할 수 있습니다.

then, catch 메서드가 Promise 객체를 반환하도록 구현하면 여러 개의 프로미스를 연결하여 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
const promise = (num) => {
  return new Promise((resolve) => {
    resolve(num * 2);
  });
};

promise(1)
  .then(promise) // 2
  .then(promise) // 4
  .then(promise) // 8
  .then((val) => console.log(val)); // 16

Promise의 정적 메서드

Promise.resolve, Promise.reject 메서드는 존재하는 값을 Promise로 래핑하기 위해 사용한다.

  • Promise.resolve
    인자로 전달된 값을 resolve하는 Promise를 생성

    1
    2
    
    const resolvedPromise = Promise.resolve([1, 2, 3]);
    resolvedPromise.then(console.log); // [ 1, 2, 3 ]
    
  • Promise.reject 인자로 전달된 값을 reject하는 Promise를 생성

    1
    2
    
    const rejectedPromise = Promise.reject(new Error("Error"));
    rejectedPromise.catch(console.log); // Error: Error
    
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.