Promise 패턴을 사용하면 1. 비동기 작업들을 순차적으로 진행하고나, 병렬로 진행하는 등의 제어가 수월해지고 2. 코드의 가독성이 좋아진다. 또한 내부적으로 예외처리에 대한 구조가 탄탄해, 오류 발생 시 3. 오류 처리에 대해 보다 직관적으로 관리해줄 수 있는 장점이 있다.
Promise는 비동기 처리가 성공(fulfilled)했는지, 실패(rejected)했는지 등의 상태 정보와 처리 종료후 실행될 콜백함수(then, catch)를 담고 있는 객체이다.
Promise는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용하며, 일반적으로 웹 애플리케이션을 구현할 때 서버에서 데이터를 요청하고 받아오기 위해 다음과 같이 사용한다.
functiongetData(callback) {// new Promise()returnnewPromise(function (resolve, reject) {$.get('url 주소/products/1',function (response) {resolve(response); // 데이터를 받으면 resolve() }); });}// getData()의 실행이 끝나면 호출되는 then()getData().then(function (data) {// resolve()의 결과 값이 전달된다.console.log(data); // $.get()의 reponse 값이 tableData에 전달됨});
위의 코드는 Promise 선언과 실행 두 부분으로 나눌 수 있다.
Promise의 states
Promise는 사전적 의미로 "약속"이다. js에서는 "지금은 없는데 이상없으면 이따가 주고 없으면 알려줄게"라는 약속으로 볼 수 있다. 따라서 promise는 다음과 같은 상태(state)를 가진다.
pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태. (약속을 수행 중인 상태)
fulfilled(이행) : 비동기 처리가 완료되어 promise가 결과 값을 반환해준 상태. (약속이 지켜진 상태)
rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태(약속이 못 지켜진 상태)
settled : 비동기 처리가 실패이든 성공이든 결론이 난 상태이다.
각 상태를 차례대로 살펴보자.
Pending
newPromise();
다음과 같이 new Promise() 메서드를 호출하면 pending 상태가 된다.
newPromise(function(resolve, reject){//...});
메서드를 호출할 때 콜백 함수의 인자로 resolve, reject 에 접근 할 수 있다.
promsie가 생성된 직후부터 resolve나 reject가 호출되기 전까지의 상태이다.
콜백 함수의 인자인 resolve를 다음과 같이 실행하면 fulfilled(이행) 상태가 된다. fulfilled상태가 되면 아래와 같이 then() 을 이용해 처리 결과 값을 받을 수 있다.
functiongetData(){returnnewPromise(function(resolve, reject){var data =100;resolve(data); });}getData().then(function(resolvedData){console.log(resolvedData);});//=> 100
Rejected
newPromise(function(resolve,reject){reject();});
콜백 함수 인자인 reject로 reject() 메서드를 실행하면 rejected(실패) 상태가된다. rejected 상태가 되면 실패한 이유(실패 처리의 결과 값)를 아래와 같이 catch() 로 받을 수 있다.
functiongetData(){returnnewPromise(function(resolve,reject){reject(newError("Request is failed")); });}getData.then().catch(function(err){console.log(err);});//=> "Request is failed"