JS

비동기 2탄 - Promise

gurwhddl 2023. 3. 22. 21:40

비동기 처리를 위해 콜백함수를 쓰게 되면 단점이 

1. 더러움

2. 에러처리가 어려움

그래서 Promise라는걸 쓰는데 - 생성자 함수이기 때문에 new 랑 같이 호출하면 프로미스 객체를 생성함

 

new Promise((resolve,reject) => {
if(성공) {
resolve()} 
else {
reject()}
)

Promise는 인수로 콜백함수를 받음 - 이 콜백함수가 비동기 처리를 수행해줌

- 이 콜백함수는 인자로 또 함수를 받음(콜백함수가 콜백함수를 받는 느낌)

 

과정을 살펴보면 

1. Promise가 인수로 전달받은 콜백 함수가 비동기 처리를 수행해줌

2. 해야될 비동기 처리를 성공하면 - 콜백 함수의 인수로 받은 resolve를 호출해주고 

3. 비동기 처리를 실패하면 - 콜백 함수의 인수로 받은 reject를 호출해준다

 

프로미스 객체에서 살펴볼 건 status , result 값인데

생성된 직후에는 status : pending / result : undefined 이다가

resolve함수를 만나면 ?  status : 'fulfilled' / result : resolve 함수의 인수

reject 함수를 만나면 ? status : 'rejected' / result : reject 함수의 인수 

resolve reject 함수는 생성된 Promise 객체의 status,result의 값을 바꿔주는 역할

* 만약에 프로미스가 pending에서 fulfilled나 rejected가 되었으면 다른 상태로는 절대 변할 수 없음

* status 값에 우리가 접근할 수 없음 === 못 바꾼다는 소리

 

프로미스 후속 메서드

프로미스의 status가 변화하면(pending에서 full or reject) 후속 메서드를 이용해서 이에 따른 후속 처리를 해줄 수 있음(변화했을 때까지 기다렸다가 -> 다음 행동)

메서드들은 모두 프로미스를 반환함

 

Promise.then(콜백1,콜백2) 

then도 두개의 함수를 인수로 받는데, 만약 프로미스의 상태가 fullfilled가 되면 ? 첫번째 콜백함수 실행 / 당연히 reject면 두번째 실행

콜백함수의 인수로는 result 값이 들어감

then의 두번째 콜백함수로는 에러 처리할때 쓸 수 있지만 잘 안씀

 

Promise.catch(콜백함수)

catch는 프로미스 값이 rejected일때만 한개의 콜백함수를 실행해줌

에러처리 할 때 사용 가능

 

Promise.finally

finally는 프로미스의 값과 상관없이 무조건 한 번 호출됨

Promise
.then(res =>  xxx)
.catch(err => xxx) 

이렇게 then에서 성공/실패 에러처리 둘다 하지 않고 나눠서 쓰는게 보편적인데
이렇게 했을 때 저 catch는 then 메서드에서 발생한 에러까지 모두 캐치해주기 때문에 이게 좋음

이 메서드들은 모두 프로미스를 반환하기 때문에 Promise.then.then.catch ~ 이렇게도 가능(프로미스 체이닝이라고 함)

 

그런데 이러면 콜백이랑 다를게 뭐냐? 똑같이 코드 더러운건 맞지 않냐?

- 그래도 좀 직관적이고, 값을 가지고 있다가 내가 필요할 때 쓸 수 있다는 점이 콜백보다는 좀 좋은점이 있음

-그리고 then catch 쓰기싫으면 async await 쓰면 됨 - 근데 또 무지성으로 이것만 쓰면 안되긴함