자바스크립트는 비동기 처리를 위한 하나의 패턴으로 콜백 함수를 사용한다. 하지만 전통적인 콜백 패턴은 콜백 헬로 인해 가독성이 나쁘고 비동기 처리 중 발생한 에러의 처리가 곤란하며 여러 개의 비동기 처리를 한번에 처리하는 데도 한계가 있다.
ES6에서는 비동기 처리를 위한 또 다른 패턴으로 프로미스(Promise)를 도입했다. 프로미스는 전통적인 콜백 패턴이 가진 단점을 보완하여 비동기 처리 시점을 명확하게 표현할 수 있다는 장점이 있다.
프로미스는 class
이기 때문에 Promise
생성자 함수를 new
연산자와 함께 호출하면 Promise 객체를 생성할 수 있다.
Promise 생성자 함수는 비동기 처리를 수행할 콜백 함수(실행자 함수, excutor)를 인수로 받는데, 이 콜백 함수는 다시 2개의 함수(resolve
, reject
)를 인수로 전달 받는다.
Promise
를 생성하는 즉시 실행자 함수가 실행되고, 함수 내부에서 비동기 작업이 이루어지며, 비동기 작업이 성공하면 resolve()
를 호출하고, 실패하면 reject()
함수를 호출한다.
- 기본 문법
let promise = new Promise(function(resolve, reject) { // excutor });
- 매개변수
- resolve(value) : 일이 성공적으로 끝난 경우 그 결과를 나타내는
value
와 함께 호출- reject(error) : 에러 발생 시 에러 객체를 나타내는
error
와 함께 호출
- 주의사항
- 만약 Promise안에 네트워크 통신을 하는 코드를 작성했다면 Promise 생성 즉시 네트워크 통신을 수행하게 되므로, 사용자가 요청하지 않았는데도 불필요한 네트워크 통신이 발생할 수 있다.
// 프로미스 생성
let promise = new Promise(function (resolve, reject) {
// 2초후 작업이 성공하면 resolve 콜백 함수를 호출하며 이때 인자로 JSX를 넘김
setTimeout(function () {
resolve('JSX')
// reject(new Error('no JSX')) -> reject는 Error라는 객체를 통해 값을 전달함
}, 2000)
});
new Promise
생성자가 반환하는 promise
객체는 pending
, fulfilled
, reject
를 내부 프로퍼티(상태, state)를 갖는다.
프로미스의 상태 정보 | 의미 | 상태 변경 조건 |
---|---|---|
pending | 비동기 처리가 아직 수정되지 않은 상태 | 프로미스가 생성된 직후 기본 상태 |
fulfilled | 비동기 처리가 수정된 상태(성공) | resolve 함수 호출 |
rejected | 비동기 처리가 수정된 상태(실패) | reject 함수 호출 |
생성된 직후의 프로미스는 기본적으로 pending
상태이며, 이후 비동기 처리가 수행되면 비동기 처리 결과에 따라 아래와 같이 프로미스 상태가 변경된다.
resolve
함수를 호출해 프로미스를 fulfiled
상태로 변경한다.reject
함수를 호출하여 프로미스를 rejected
상태로 변경한다.fulfilled
또는 rejected
상태를 settled
상태라고 한다. settled
상태는 fulfilled
또는 rejected
상태와 상관 없이 pending
이 아닌 상태로 비동기 처리가 수행된 상태를 말한다.
프로미스는 pending
상태에서 settled
상태로 변화할 수 있지만, 일단 settled
상태가 되면 더이상 다른 상태로 변화할 수 없다.
프로미스는 비동기 처리 상태와 더불어 비동기 처리 결과도 상태로 갖는다.
- 비동기 처리가 성공하면 프로미스는
pending
상태에서fulfilled
상태로 변화한다. 그리고 비동기 처리 결과인 1을 값으로 가진다.
- 비동기 처리가 실패하면 프로미스는
pending
상태에서rejected
상태로 변화한다. 그리고 비동기 처리 결과인Error
객체를 값으로 갖는다. 즉, 프로미스는 비동기 처리 상태와 처리 결과를 관리하는 객체다.