[Javascript] 비동기 처리 - Promise

TaeHyeon·2020년 1월 30일
0
post-thumbnail

Promise가 등장하기 전까지 자바스크립트에서는 모든 비동기 처리를 callback 함수로 처리해 왔다. 하지만 callback 함수는 중첩이 될수록 에러처리가 매우 어려워지고 사람이 이해하기 힘든 코드가 되기 때문에 callback hell이라는 말까지 생기게 되었다.

그래서 비동기 처리를 쉽게 하기 위해 es2015에서는 Promise라는 문법이 추가 됐다.

Promise

Promise는 비동기 함수의 성공이나 실패를 나타내는 객체다. Promise를 사용하기 위해 Promise 생성자 함수를 이용해야한다.

Promise의 생성자 함수는 인자로 비동기 함수를 받는다. 그리고 비동기 함수는 다시 두개의 인자를 받는다.

resolve

비동기 작업이 성공적으로 끝나면 실행하는 함수다. 인자로 실행한 비동기 함수의 결과값을 받고 resolve는 다시 Promise를 리턴한다. then을 이용해 다음 비동기 작업을 순차적으로 이어나갈 수 있다.

reject

비동기 작업중 에러가 발생할 경우 실행하는 함수다. reject 함수가 실행되면 catch를 이용해 에러를 처리할 수 있다.

간단한 예제

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

promise(); 
//Promise {<pending>}
//__proto__: Promise
//[[PromiseStatus]]: "resolved"
//[[PromiseValue]]: 1

promise함수를 실행하면 Promise 객체가 리턴된다. 이제 이 객체로 비동기 작업을 이어나갈 수도 에러를 처리 할 수도있다.

Promise의 3가지 상태

Promise는 3가지 상태중 하나를 가질 수 있다. 위의 코드에서 Promise는 현재 대기 상태다.

  • 대기(pending): 이행하거나 거부되지 않은 초기 상태.
  • 이행(fulfilled): 연산이 성공적으로 완료되면 Promise를 리턴한다.
  • 거부(rejected): 연산이 실패하면 catch를 이용해 에러를 처리 할 수 있다.

then을 이용한 Promise Chaining

일반적으로 비동기 작업은 여러개의 비동기 함수를 순차적으로 실행한다. 이제 callback 대신 then을 이용한 Promise Chain을 이용해 비동기 작업을 처리 할 수 있다.

then 함수의 인자로 들어오는 함수로 resolve된 결과 값을 받을 수 있고 then 함수는 항상 Promise를 리턴한다.

const promise1 = function() {
  const user = {};
  
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
      user.name = 'foo';
      user.age = 10;
      console.log(user);
      resolve(user);
    }, 1000);
  });
};

promise1().then(user => {
  setTimeout(() => {
    user.iq = 100;
    console.log(user);

    return user;
  }, 2000);
});
//{name: "foo", age: 10}
//{name: "foo", age: 10, iq: 100}

catch를 이용한 에러처리

catch를 이용해 에러를 처리 할 수 있다. 일반적으로 Chaining 마지막에 사용한다

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

promise1()
  .then(result => {
    throw new Error('err!!!');
  })
  .catch(err => console.log(err));
//Error: err!!!

이렇게 catch를 이용해 에러를 잡으면 프로그램이 중단되지 않고 다음 코드가 실행된다.

0개의 댓글