프로미스 객체다
프로미스는 ECMAScript 사양에 정의된 표준 빌트인 객체다.
프로미스는 비동기 처리의 상태와 결과 값을 나타내는 객체다.
ES6에서 비동기 처리르 위한 패턴으로 프로미스를 도입했다..!
프로미스는 전통적인 콜백 패턴이 가진 단점을 보완하며 비동기 처리 시점을 표현할 수 있다.
asyncFunction('/step1', a => {
asyncFunction(`/step2/${a}`, b => {
asyncFunction(`/step3/${b}`, c => {
asyncFunction(`/step4/${c}`, d => {
console.log(d)
});
});
});
});
콜백 헬은 가독성을 나쁘게 하며 실수를 유발시킨다. 또한 비동기 처리를 위한 콜백 패턴에서 가장 큰 문제는 에러 처리가 어렵다는 것!
Promise 생성자 함수를 new 연산자와 함꼐 호출하면 프로미스 객체를 생성한다.
Promise 생성자 함수는 비동기 처리를 수행할 콜백 함수를 인자로 전달 받는다. 이 콜백 함수는 다시 resolve, reject 함수를 인자로 전달 받는다.
const promise = new Promise((resolve, reject)=>{
// Promise 함수의 콜백 함수 내부!! 에서 비동기 처리를 수행
if(/*비동기 처리 성공시*/){
resolve('result')
} else {
/*비동기 처리 실패시*/
reject('failure reason')
}
})
Promise 생성자 함수가 인자로 받은 콜백 함수 내부에서 비동기 처리를 수행한다.
이 비동기 처리가 성공하면 콜백 함수의 첫번째 인자로 전달된 resolve 함수를 호출하고, 비동기 처리에 실패하면 두번째 인자인 reject 함수를 호출한다.
프로미스는 비동기 처리가 어떻게 진행되고 있는지 Status 정보를 갖는다.
비동기 처리가 성공하면 resolve 함수를 호출해 프로미스를 fulfilled 상태로 변경하고
비동기 처리가 실패하면 reject 함수를 호출해 프로미스를rejected 상태로 변경한다.
fulfilled 또는 rejected 상태를 settled 상태라고 하며 성공, 실패 여부 상관없이 비동기 처리가 수행된 상태를 뜻한다. settled 상태가 되면 더는 다른 상태로 변화할 수 없음!
프로미스는 비동기 처리 상태와 더불어 비동기 처리 결과도 상태로 갖는다.
예시와 같이 PromiseStatus와 PromiseResult를 갖는다.
⬆︎ 비동기 처리가 성공하면 fulfilled상태로 변경, 결과 값은 1
⬆︎ 비동기 처리가 실패하면 rejected상태로 변경, 결과 값은 Error 객체
프로미스는 비동기 처리 상태 와 처리 결과 를 관리하는 객체다!
프로미스의 비동기 처리상태가 변화하면 이에 따른 후속 처리를 해야한다. fulfilled가 되면 처리 결과를 가지고 후속 처리를 하고 rejected가 되면 error 처리를 해줘야한다.
프로미스는 후속 메서드로 then, catch, finally 를 제공한다.
프로미스의 비동기 처리 상태가 변하면 후속 처리 메서드에 인수로 전달한 콜백 함수가 선택적으로 호출된다. 이 때 콜백 함수에 프로미스의 결과 값이 콜백 함수의 인자로 전달된다!!
모든 후속 처리 메서드는 프로미스를 리턴하며 비동기로 동작한다.
then 은 두 개의 콜백함수를 인자로 전달받는다.
then은 항상 프로미스로 반환하는데, then의 콜백 함수가 프로미스가 아닌 값을 반환하면 자동적으로 resolve 또는 reject하여 프로미스를 생성해 반환한다.
catch는 한 개의 콜백 함수를 인자로 전달받는다.
프로미스가 rejected 상태가 된 경우에만 호출된다.
catch는 then(undefined, onRejected)과 동일하게 동작하므로 언제나 프로미스를 반환한다.
new Promise((_, reject) => reject(new Error('rejected!')))
.catch(err => console.log(err))
// Error: rejected!
new Promise((_, reject) => reject(new Error('rejected!')))
.then(undefined, err => console.log(err))
// Error: rejected!
catch 메서드를 호출하면 내부적으로 then(undefined, onRejected)을 호출한다.
단, then 메서드의 두 번째 콜백 함수는 첫 번째 콜백 함수에서 발생한 에러를 캐치하지 못하고 코드가 복잡해져 가독성에도 좋지않다.
catch 메서드를 모든 then 메서드를 호출한 이후에 호출하면 비동기 처리에서 발생한 에러뿐만 아니라 then 메서드 내부에서 발생한 에러까지 모두 캐치할 수 있다. 이 방법이 가독성도 더 좋기때문에 에러처리는 catch를 사용하는 것을 권장한다고 한다.
finally는 한 개의 콜백 함수를 인자로 전달받는다.
프로미스의 상태와 상관없이 무조건 한 번 호출된다.
역시 프로미스를 반환한다.
스터디 by 자바스크립트 Deep dive