Promise

오민영·2021년 7월 14일
0

Web API

목록 보기
7/9
post-thumbnail

비동기적으로 실행하는 작업의 결과(성공/실패)를 나타내는 객체이다.
비동기 결과를 객체화 시킨다는 점이 Promise의 가장 큰 장점이자 특징이다!

Promise는 콜백을 예측 가능한 패턴으로 사용할 수 있게 해주며, Promise 없이 콜백만 사용했을 때 나타날 수 있는 엉뚱한 현상이나 찾기 힘든 버그를 상당 수 해결한다.

Promise 기본 개념

Promise 기반의 비동기적 함수를 호출하면, 해당 함수가 인스턴스를 반환한다.
Promise는 성공(fullfilled)하거나, 실패(Rejected) 둘 중 하나이다.

Promise 기초 코드

Resolve와 Reject 콜백이 있는 함수로, 새 Promise 인스턴스를 만들면 된다.

// jQuery의 ajax 통신
function getData(callbackFunc) {
  $.get('url 주소/products/1', function(response) {
    callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
  });
}

getData(function(tableData) {
  console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});

// Promise의 ajax 통신
function getData(callback){
  // new Promise() 추가
  return new Promise(resolve, reject){
    $api.get('url/products/1', function(response){
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    })
  })
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData){
  // resolve()의 결과 값이 여기로 전달된다.
  console.log(tableData);
}
      

Promise 3가지 상태(states)

프로미스 상태는 프로미스의 처리 과정을 의미하는데, 처리 과정은 new Promise()를 생성하고, 종료될 때까지 3가지 상태를 갖는다!

  • Pending(대기): 비동기 처리 로직이 아직 완료되지 않은 상태
  • Fulfilled(성공): 비동기 처리가 완료되어, Promise가 결과 값을 반환해준 상태
  • Rejected(실패): 비동기 처리가 실패하거나 오류가 발생한 상태

new Promise(Promise 생성자 함수)가 인자로 전달받은 콜백함수는, 내부에서 비동기처리 작업을 한다.

  • 비동기 처리가 성공하면, 콜백 함수릐 인자로 전달받은 resolve 함수를 호출하고, 이 때 프로미스는 fulfilled(성공) 상태가 된다.
  • 비동기 처리가 실패하면 reject 함수를 호출하고, 이 때 프로미스는 rejected(실패) 상태가 된다.

Pending

먼저 아래와 같이 new Promise()(생성자 함수) 메서드를 호출하면 대기(Pending) 상태가 된다.

new Promise()

new Promise() 메서드를 호출할 때 콜백함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject이다.

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

Fulfilled

여기서 콜백 함수 인자 resolve를 아래와 같이 실행하면 성공(Fulfilled)상태가 된다.

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

그리고, 이행 상태가 되면 아래와 같이 then() 을 이용하여 처리 결과 값을 받을 수 있다.

function getData(){
  return new Promise(function(resolve, reject){
    var data = 100;
    resolve(data);
  })
}

// resolve()의 결과 값인 data를 resolveData로 받음
getData().then(function(resolveData){
  console.log(resolveData); // 100
})
                     

Rejected

new Promise()(생성자 함수)로 프로미스 객체를 생성하면 콜백함수 인자로 resolve와 reject를 사용할 수 있다고 했다.
여기서 reject를 아래와 같이 호출하면 실패 상태가 된다.

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

그리고, 실패 상태가 되면 실패한 이유(실패 처리의 결과값)을 catch()로 받을 수 있다.

function getData(){
  return new Promise(function(resolve, reject){
    reject(new Error('Request is Faild'));
  })
}

// reject()의 결과 값 error를 error에 받는다.
getData().then().catch(function(error){
  console.log(error); // Error: Request is failed
})

Promise (then / catch) 후속 처리 메소드

new Promise로 구현된 비동기 함수는 Promise 객체를 반환해야 한다. Promise로 구현된 비동기 함수를 호출하는 측에서는 Promise 객체의 후속 처리 메소드(then, catch)를 통해 비동기 처리 결과? 또는 에러 메세지를 전달 받아 처리한다.

Promise 객체는 상태를 갖기 때문에, 이 상태에 따라 후속 처리 메소드를 체이닝 방식으로 호출한다.

then

  • then() 메소드는 두 개의 콜백 함수를 인자로 전달 받는다.
  • 첫 번째 콜백함수는 성공(fulfilled, resolve 함수가 호출된 상태)시 호출되고,
  • 두 번째 콜백함수는 실패(rejected, reject 함수가 호출된 상태)시 호출된다.
  • then() 메소드는 Promise를 반환한다.

catch

  • cathc() 메소드는 예외(비동기 처리에서 발생한 에러와 then 메소드에서 발생한 에러)가 발생한다.
  • catch() 메소드는 Promise를 반환한다.

Promise 예제

기본 예제

function getData(){
  return new Promise(function(resolve, reject){
    $.get('url 주소/products/1', function(response){
      if(response){
        resolve(response);
      }
      reject(new Error('Request is Faild'));
    })
  })
  
  // $.get 호출 결과에 따라 response 또는 error 출력
  getData().then(function(data){
    console.log(data) // response 값 출력
  }).catch(function(error){
    console.error(error) // Error 출력
  })

Promise Chaning(여러 개의 프로미스 연결하기)

function getData(){
	return new Promise({
    // ...
    })
}

// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
	.then(function(data){
  		// ...
	})
	.then(function(){
  		// ...
	})
	.then(function(){
  		// ...
	})
	.then(function(){
  		// ...
	})

비동기 처리 예제에서 가장 흔하게 사용되는 setTimeout() API

new Promise(function(resolve, reject){
  setTimeout(function(){
    resolve(1)
  }, 20000)
})
.then(function(result){
	console.log(resulte);
  	return result + 10
})
.then(function(result){
	console.log(result);
  	return result + 20
})
.then(function(result){
	console.log(result);
})

Promise 에러 처리 방법

실제 서비스를 구현하다 보면 네트워크 연결, 서버 문제 등으로 인해 오류가 발생할 수 있다.
Promise 에러 처리 방법에는 2가지 방법이 있다.

1. then()의 두 번째 인자로 에러를 처리하는 방법

getData().then(handleSuccess, handleError);

2. catch()를 이용하는 방법

getData().then().catch();

예시

위 두가지 방법 모두 promise의 reject() 메서드가 호출되어 실패 상태가 된 경우에 실행된다.
가급적 catch()로 에러를 처리하는 게 더 효율적이다.

function getData(){
  return new Promise((resolve, reject){
    reject('failed');
})}

// 1. then()의 두 번째 인자로 에러를 처리하는 코드
getData().then(function(){
  // ...
}, function(error){
  console.log(error);
})

// 2. catch()로 에러를처리하는 코드
getData().then().catch(function(error){
  console.error(error);
})

Reference

참고

profile
이것저것 정리하는 공간

0개의 댓글