Promise(프로미스)
javascript는 비동기 처리를 위한 하나의 패턴으로 콜백 함수를 사용한다.
하지만 이 전통적인 콜백 패턴은 가동석이 나쁘고 비동기 처리중 발생한 에러의 예외 처리가 곤란하며 여러 개의 비동기
처리 로직을 한꺼번에 처리하는 것도 한계가 뚜렷하다.
비동기 처리를 위해 콜백 패턴을 사용하면 처리 순서를 보장하기 위해 여러 개의 콜백 함수가 중첩되어 복잡도가 높아지는 콜백 헬이 발생하는 단점도 있다.
▼▼콜백 헬이 발생하는 사례▼▼
step1(function(value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
step5(value4, function(value5) {
// value5를 사용하는 처리
});
});
});
});
});
콜백 헬이 발생하는 이유는 비동기 처리는 실행 완료를 기다리지 않고 다음 로직을 실행한다.
따라서 비동기 함수 내에서 처리 결과를 반환하면 기대한 대로 동작하지 않는다.
이 문제점을 보완한 Promise가 ES6에서 도입됬다.
Promise는 Promise 생성자 함수를 통해 인스턴스화한다.
Promise 생성자 함수는 비동기 작업을 수행 할 콜백 함수를 인자로 전달받는데 이 콜백 함수는 resolve와 reject 함수를
인자로 전달받는다.
// Promise 객체의 생성
const promise = new Promise((resolve, reject) => {
// 비동기 작업을 수행한다.
if (/* 비동기 작업 수행 성공 */) {
resolve('result');
}
else { /* 비동기 작업 수행 실패 */
reject('failure reason');
}
});
Promise는 비동기 처리가 성공(fulfilled)했는지 실패(rejected)했는지 등의 상태 정보를 갖는다.
상태 | 의미 | 구현 |
---|---|---|
pending |
비동기 처리가 아직 수행되지 않은 상태 |
resolve 또는 reject 함수가 아직 호출되지 않은 상태 |
fulfilled |
비동기 처리가 수행된 상태(성공) | resolve 함수가 호출된 상태 |
rejected |
비동기 처리가 수행된 상태(실패) | reject 함수가 호출된 상태 |
settled |
비동기 처리가 수행된 상태 (성공 또는 실패) |
resolve 또는 reject 함수가 호출된 상태 |
const promiseAjax = (method, url, payload) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader("Content-type", "application/json");
xhr.send(JSON.stringify(payload));
xhr.onreadystatechange = function() {
// 서버 응답 완료가 아니면 무시
if (xhr.readyState !== XMLHttpRequest.DONE) return;
if (xhr.status >= 200 && xhr.status < 400) {
// resolve 메소드를 호출하면서 처리 결과를 전달
resolve(xhr.response); // Success!
} else {
// reject 메소드를 호출하면서 에러 메시지를 전달
reject(new Error(xhr.status)); // Failed...
}
};
});
};
Promise 후속 처리 메서드
Promise로 구현된 비동기 함수는 Promise 객체를 반환해야한다.
Promise로 구현된 비동기 함수를 호출하는 caller는 Promise 객체의 후속 처리 메서드를 통해 비동기 처리 결과 또는
에러 메시지를 전달받아 처리한다.
Promise 객체는 상태를 갖고있다고 했는데 이 상태에 따라 후속 처리 메서드를 체이닝 방식으로 호출한다.
then
then 메서드는 두 개의 콜백 함수를 인자로 전달 받는다.
첫번째 콜백 함수는 성공(resolve 함수가 호출된 상태)시 호출되고 두번째 함수는 실패(reject 함수가 호출된 상태)시 호출된다.
이 then 메서드는 Promise를 반환한다.
catch
예외(비동기 처리에서 발생한 에러와 then 메서드에서 발생한 에러)가 발생하면 호출된다.
이 catch 메서드는 Promise를 반환한다.
비동기 함수의 처리 결과를 가지고 다른 비동기 함수를 호출해야 하는 경우 함수의 호출이 중첩되어 복잡도가 높아지는
콜백 헬이 발생한다.
Promise는 후속 처리 메서드를 체이닝하여 여러 개의 Promise를 연결하여 사용할 수 있는데 이것으로 콜백 헬을 해결한다.