Promise
는 비동기 작업이 맞이할 미래의 완료 혹은 실패와 그 값을 가지고 있는 객체이다.
프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환할 수 있다. 다만 최종 결과를 반환하는 것이 아니고, 미래의 어떤 시점에 결과를 제공하겠다는 약속(Promise)를 제공한다.
Promise
는 세 가지 상태를 가진다.
프로미스에 거부 처리기 콜백을 추가하고, 콜백이 호출될 경우 그 반환값으로 이행하며 호출되지 않을 경우, 즉 이전 프로미스가 이행하는 경우 이행한 값을 그대로 사용해 이행하는 새로운 프로미스를 반환한다.
프로미스의 이행과 거부 여부에 상관없이 처리될 경우 항상 호출되는 처리기 콜백을 추가하고, 이행한 값 그대로 이행하는 새로운 프로미스를 반환한다.
프로미스에 이행과 거부 처리기 콜백을 추가하고, 콜백이 호출될 경우 그 반환값으로 이행하며 호출되지 않을 경우 처리된 값과 상태 그대로 처리되는 새로운 프로미스를 반환한다.
출처: MDN
doSomething(function (result) {
doSomethingElse(
result,
function (newResult) {
doThirdThing(
newResult,
function (finalResult) {
console.log("Got the final result: " + finalResult);
},
failureCallback,
);
},
failureCallback,
);
}, failureCallback);
예전에 사용하던 여러 비동기 작업을 연속적으로 사용하던 콜백 지옥이다. 한눈에 봐도 어지럽다. 이를 프로미스를 사용하게 되면서 promise chain을 만들며 해결할 수 있다.
doSomething()
.then(function (result) {
return doSomethingElse(result);
})
.then(function (newResult) {
return doThirdThing(newResult);
})
.then(function (finalResult) {
console.log("Got the final result: " + finalResult);
})
.catch(failureCallback);
콜백에서 넘어가는 인자 result
,newResult
,finalResult
들은 선택 옵션이다. 이를 화살표 함수로 변환하면
doSomething()
.then((result) => doSomethingElse(result))
.then((newResult) => doThirdThing(newResult))
.then((finalResult) => {
console.log(`Got the final result: ${finalResult}`);
})
.catch(failureCallback);
훨씬 깔끔하게 볼 수 있다.
new Promise((resolve, reject) => {
console.log("Initial");
resolve();
})
.then(() => {
throw new Error("Something failed");
console.log("Do this");
})
.catch(() => {
console.log("Do that");
})
.then(() => {
console.log("Do this, whatever happened before");
});
이 코드의 출력은 어떻게 나올까?
Initial
Do that
Do this, whatever happened before
이렇게 나온다. "Do This"
가 없는 이유는 첫 체인에서 "Something failed"
에러를 throw
시켰기 때문에 에러가 발생해 .catch()
로 넘어가 "Do that"
이 출력되는 것이다.
예시 및 코드 출처: MDN