45. 프로미스
2025. 1. 7. 16:35ㆍ기록/Modern JavaScript Deep Dive
- 목차
비동기 처리를 위한 콜백 패턴의 단점
- 비동기 함수는 비동기 처리 결과를 외부에 반환할 수 없고, 상위 스코프의 변수에 할당할 수도 없음
- 따라서 비동기 함수의 처리 결과에 대한 후속 처리는 비동기 함수 내부에서 수행해야 함
- 이때 비동기 함수에 콜백 함수를 전달하는 것이 일반적임
- 하지만 후속 처리를 수행하는 비동기 함수가 비동기 처리 결과를 가지고 또다시 비동기 함수를 호출해야 한다면
콜백 함수 호출이 중첩되어 복잡도가 높아지는 현상이 발생 (콜백 지옥)
- 또한 에러 처리가 곤란하다는 문제가 있어 이를 극복하기 위해 ES6에서 프로미스가 도입됨
프로미스의 생성
const promise = new Promise((resolve, reject) => {
// Promise 함수의 콜백 함수 내부에서 비동기 처리 수행
if (/* 비동기 처리 성공 */) {
resolve('result');
} else { /* 비동기 처리 실패 */
reject('failure reason');
}
});
- Promise 생성자 함수를 new 연산자와 함께 호출하면 프로미스를 생성함
- Promise 생성자 함수는 비동기 처리를 수행할 콜백 함수를 인수로 전달받음 (resolve, reject 함수)
- Promise 생성자 함수가 인수로 전달받은 콜백 함수 내부에서 비동기 처리를 수행함
프로미스의 상태 정보 | 의미 | 상태 변경 조건 |
pending | 비동기 처리가 아직 수행되지 않은 상태 | 프로미스가 생성된 직후 기본 상태 |
fulfilled | 비동기 처리가 수행된 상태 (성공) | resolve 함수 호출 |
rejected | 비동기 처리가 수행된 상태 (실패) | reject 함수 호출 |
- 프로미스는 비동기 처리 상태 정보를 가짐
- 생성된 직후의 프로미스는 pending 상태
- 비동기 처리 성공 시 resolve 함수를 호출해 fulfilled 상태로 변경
- 비동기 처리 결과값을 가짐
- 비동기 처리 실패 시 reject 함수를 호출해 rejected 상태로 변경
- 비동기 처리 결과인 Error 객체를 값으로 가짐
settled 상태
- fulfilled / rejected 상태
- pending이 아닌 상태로 비동기 처리가 수행된 상태
프로미스는 비동기 처리 상태와 처리 결과를 관리하는 객체이다.
프로미스의 후속 처리 메서드
모든 후속 처리 메서드는 프로미스를 반환하며 비동기로 동작함
1. then
// fulfilled
new Promise(resolve => resolve('fulfilled'))
.then(v => console.log(v), e => console.error(e)); // fulfilled
// rejected
new Promise(_, reject) => reject(new Error('rejected')))
.then(v => console.log(v), e => console.error(e)); // Error: rejected
- 두 개의 콜백 함수를 인수로 전달받음
- 첫 번째 콜백 함수
- 프로미스가 fulfilled 상태가 되면 호출됨
- 콜백 함수는 프로미스의 비동기 처리 결과를 인수로 전달받음
- 두 번째 콜백 함수
- 프로미스가 rejected 상태가 되면 호출됨
- 콜백 함수는 프로미스의 에러를 인수로 전달받음
- 첫 번째 콜백 함수
2. catch
// rejected
new Promise((_, reject) => reject(new Error('rejected')))
.catch(e => console.log(e)); // Error: rejected
- 한 개의 콜백 함수를 인수로 전달받음
- catch 메서드의 콜백 함수는 프로미스가 rejected 상태인 경우만 호출됨
3. finally
new Promise(() => {})
.finally(()) => console.log('finally')); // finally
- 한 개의 콜백 함수를 인수로 전달받음
- 프로미스의 성공/실패와 상관없이 무조건 한 번 호출됨
프로미스의 에러 처리
promiseGet(url)
.then(res => console.xxx(res))
.catch(err => console.error(err)); // TypeError: console.xxx is not a function
- catch 메서드를 사용해 처리하는 것이 바람직함
- 모든 then 메서드를 호출한 이후에 catch 메서드 호출 시 비동기 처리에서 발생한 에러(rejected 상태) 뿐만 아니라
then 메서드 내부에서 발생한 에러까지 모두 캐치 가능
프로미스 체이닝