Promise

Happhee·2022년 5월 12일
2

AvenJS

목록 보기
13/17
post-thumbnail

비동기 프로그래밍을 구현하기 위해 가장 먼저 사용된 방법이 callBack이었지만, callBack hell이라는 치명적인 문제점이 발생되었다.

이를 해결하기 위해 나타난 Promise에 대해 살펴보자.


✨Promise

자바스크립트 비동기 처리에 사용되는 객체이다.

비동기 작업에 대한 상태와 결과를 가져와주는 역할을 한다.

간단한 예제를 통해 기존의 콜백방식과 프로미스를 비교해보자.

  • callback
function getData(callbackFunc){
	$.get('주소/users?id=1', function(res){
      callbackFunc(res);
    });
}
getData(function(userData)){
        console.log(userData);
});

콜백함수로 유저의 데이터를 가져와서 출력해주는 함수를 전달하였다.
여기에 프로미스를 적용해보자.

  • promise
function getData(callbackFunc){
	return new Promise(function(resolve, reject){
      $.get('주소/users?id=1', function(res){
        callbackFunc(res);
      });
    });
}
getData().then(function(userData)){
        console.log(userData);
});

똑같이 유저의 데이터를 가져오는 함수이지만, getData().then()을 실행하여 프로미스가 resolve를 호출하면 유저의 데이터를 출력한다.

🤔 Promise의 객체는 어떻게 생성할 수 있을까?

앞의 예제 코드로 살펴보았듯이 new Promise(executor)를 사용하여 Promise 객체를 만들 수 있다.

function createPromise(something) {
  return new Promise(function(resolve, reject) {
    
    if (비동기 작업 성공) {
      resolve(value);
    } else { // 비동기 작업 실패
      reject(error);
    }    
  });
}
const promiseInstance = createPromise(something);
  • resolve(value)
    작업 완료 후 성공적으로 가져온 결과값 value를 인자로 받는다.
  • reject(error)
    작업 실패, 즉 에러 발생 시 에러 객체를 error를 인자로 받는다.

✨ 상태

Promise 객체를 생성한 직후에는 pending(대기/보류) 상태를 가지게 된다. 여기서 resolve를 호출하면 fulfilled(이행)으로 변환되고, reject가 호출되면 rejected(거부/실패)로 변환된다.

처리 결과에 따라 한 번 지정된 상태는 변경되지 않는다.

pending

비동기 처리가 아직 수행되지 않은 상태

👉 resolve또는 reject가 아직 호출되지 않은 상태이다.

new Promise(function(resolve, reject){
  //...
});

콜백 함수의 인자로 resolve, reject를 넘겨 pending 이후의 상태에 대한 처리를 수행할 수 있도록 한다.

fulfilled

비동기 처리가 성공한 상태

👉 resolve 함수가 호출된 상태이다.

function getFruit(){
  return new Promise(function(resolve, reject){
    let fruit = 'orange';
    resolve(fruit);
  });
}
getFruit().then(function(resolvedData){
  console.log(resolvedData);
});

resolvedData로 fruit이 전달되었고, PromiseState가 fulfilled임을 알 수 있다.

rejected

비동기 처리가 실패한 상태

👉 reject 함수가 호출된 상태이다.

function getFruit(){
  return new Promise(function(resolve, reject){
    let fruit = 'orange';
    reject(new Error('❗️ failed ❗️'));
  });
}
getFruit().catch(function(err){
  console.log(err);
});

Promise 객체 내부의 프로퍼티 state, result의 직접 접근을 불가능하고, then, catch를 이용하여 접근할 수 있다는 것을 알 수 있게 되었다.

  • Promise 생성자 함수
  • then
  • catch
  • finally

❗️ 에러 처리 ❗️

then( )

Promise 객체의 결과 값을 사용해 추가적인 작업을 할 때, then 메소드를 사용한다.

promise.then(onFulfilled, onRejected?)

  • onFulfilled
    Promise가 성공했을 때, 실행되는 콜백 함수로 결과 값을 인자로 받는다.
  • onRejected
    Promise가 실패했을 때, 실행되는 콜백 함수로 에러 객체를 인자로 받는다.
  • return
    Promise 객체
promise.then(
  function(result){ }	// handleSuccess
  function(error){ }	// handleError
);

만약, 작업이 성공한 경우만 다루려면 then에 하나의 handler만 전달하면 된다.

catch( )

예외 처리를 위해 사용되는 메소드이다.

promise.catch(onRejected)

  • onRejected
    Promise가 실패했을 때, 실행되는 콜백 함수로 에러 객체를 인자로 받는다.
  • return
    Promise 객체
promise.then().catch(function(err) {
  console.log(err);
});

아래의 2가지 방법으로 Promise의 reject메서드가 호출되어 실패일때만 실행한다.

function getFruit(){
  return new Promise(function(resolve, reject){
    reject(new Error('❗️ failed ❗️'));
  });
}

getFruit()
  .then(function(){},function(err){
  console.log(err);
})

getFruit()
  .then()
  .catch(function(err){
  console.log(err);
})

finally

Promise의 이행 및 거부 상태에 관계 없이 처리된 경우 무조건 실행되는 메소드이다.

promise.catch(onFinally)

  • onFinally
    Promise가 처리된 후 실행되는 콜백 함수로 어떤 인자도 받지 않는다.
  • return
    Promise 객체
function getFruit(){
  return new Promise(function(resolve, reject){
    let fruit = 'orange';
    resolve(fruit);
  });
}
getFruit()
  .finally(()=> console.log('👜 과일 가져오기 준비 👜'))
  .then(function(resolvedData){
  console.log(resolvedData);
})
  .finally(()=> console.log('🍊 과일 가져오기 완료 🍊'))

Promise의 성공/실패 여부에 관계없이 실행되는 것을 알 수 있다.

즉, finally는 프라미스 결과를 처리하기 위해 만들어진 메소드가 아니다!


📚 학습할 때, 참고한 자료 📚

profile
즐기면서 정확하게 나아가는 웹프론트엔드 개발자 https://happhee-dev.tistory.com/ 로 이전하였습니다

0개의 댓글