프로미스의 상태 (state)
1. 수행중일 때 -> pending 상태
2. 수행이 다끝나면 -> fulfilled 상태
3. 에러가 난다면 -> rejected 상태
Promise 는
정보를 제공하는 producer와
정보를 소비하는 consumer
로 나누어 진다.
const promise = new Promise(( 1-1) resolve,reject) => {
console.log('doing something...')
setTimeout(() => {
1-2) resolve('bosule')
1-3) reject(new Error('no network') //=> Uncaught (in promise) Error: no network
},2000);
})
1. resolve : 기능을 정상적으로 수행해서 마지막 최종 데이터를 전달
2. reject : 기능을 수행하다가 중간에 문제가 생기면 호출
* 유의할점
새로운 promise가 만들어 질때는 전달한 ececutor(resolve, reject) 함수가 자동적으로 바로 실행이 되는데,
예를 들어 클릭후에 데이터를 요청해야하는 경우에는 promise에 대해 다시 생각을 해볼 필요가 있다.
성공적으로 네트워크 또는 파일에서 읽어온 사용자를 받아왔을 경우 resolve를 호출하면서 bosule값을 전달해준다.
resolve 대신 reject를 호출할경우 에러 메세지 발생
promise
2-1)
.then((value) =>{
console.log(value); // 2초 뒤에 bosule 출력
})
2-2)
.catch((error) =>{
console.log(error);
})
2-3)
.finally(() =>{
console.log('finally');
})
값이 정상적으로 잘 수행이 되어서 resolve 상태가 된다면 callback 함수에서 전달된 위에 bosule 이라는 값이 들어오게 된다.
에러 reject가 발생했을때 어떻게 처리할건지 callback 함수를 작성
예시에서는 에러 메세지 를 콘솔로 출력할 수 있도록 설정
.finally 작성 시 성공 됏을경우에도 호출 되고 실패했을 경우에도 호출
어떤기능을 마지막으로 수행하고 싶을때 사용
const fetchNumber = new Promise((resolve,reject) =>{
setTimeOut(() =>{
resolve(1)
},1000)
})
fetchNumber()
.then(num => num * 2) // 2
.then(num => num * 2) // 2가 전달되서 결과 6
.then(num => {
return new Promise((resolve,reject) =>{
setTimeout(() =>{
resolve(num -1)
},1000)
})
})
.then(num => console.log(num));
.then은 값을 전달할수 도 있고 promise를 전달할수도 있다.
const getHen = () =>
new Promise((resolve,reject) => {
setTimeout(() => {
resolve('🐔');
},1000);
});
const getEgg = (hen) =>
new Promise((resolve,reject) => {
setTimeout(() => {
resolve(`${hen} => 🥚`);
},1000)
})
const cook = egg =>
new Promise((resolve,reject) =>{
setTimeout(() =>{
console.log(`${egg} => 🍳`);
},1000)
})
4-1)
getHen()
.then((hen) => getEgg(hen))
.then((egg) => cook(egg))
.then((meal) => console.log(meal))
어렵다고 느껴졌는데 3번 코드와 비교해보면 비교적 쉽게 이해가 가는거 같다.
나의 관점에서 해석해보자면
getHen() // getHen에서 성공됐을때 resolve가 호출 => 🐔을 뱉음
.then((🐔) => getEgg(🐔)) //getEgg에 🐔이 담기고 getEgg가 성공시 resolve호출되면 🐔 => 🥚 뱉음
.then((🐔 => 🥚) => cook(🐔 => 🥚)) //getEgg가 뱉은 🐔 => 🥚가 담겨 cook가 성공시 resolve호출되면 🐔 => 🥚 => 🍳뱉음
.then((🐔 => 🥚 => 🍳) => console.log(meal)) //cook가 뱉은 🐔 => 🥚 => 🍳 전달되면 console 결과값은 🐔 => 🥚 => 🍳
대략 내가 생각한 비동기 방식은 이렇다!
위에 코드를 더 간단하게 작성하자면 아래와 같이 작성할 수있다.
getHen()
.then(getEgg)
.then(cook)
.then(console.log)
const getHen = () =>
new Promise((resolve,reject) => {
setTimeout(() => {
resolve('🐔');
},1000);
});
const getEgg = (hen) =>
new Promise((resolve,reject) => {
setTimeout(() => {
5-1)
reject(() => {
new Error(`error ! ${hen} => 🥚`) //결과 Uncaught (in promise) Error: error! 🐔 => 🥚
})
},1000)
})
const cook = egg =>
new Promise((resolve,reject) =>{
setTimeout(() =>{
console.log(`${egg} => 🍳`);
},1000)
})
getHen()
.then((hen) => getEgg(hen))
.then((egg) => cook(egg))
.then((meal) => console.log(meal))
4.의 코드를 가져와서 reject 즉 실패시에 코드를 나타내면 에러핸들링을 하지 않았기 때문에 콘솔에서 결과값은 'Uncaught (in promise) Error: error! 🐔 => 🥚로 호출된다.
그래서 .catch로 error handling 하면 아래와 같이 작성을 추가해주면 된다.
getHen()
.then((hen) => getEgg(hen))
.then((egg) => cook(egg))
.then((meal) => console.log(meal))
.catch((error) => console.log(error)); //결과 error ! 🐔 => 🥚
.catch 에러 핸들링 역시 실패시 reject를 호출 하게 되고 담겨있던 new Error(error ! ${hen} => 🥚
) 은 .catch(error ! ${hen} => 🥚
) 라고 생각해주면 된다.
그럼 console에서는 reject안에 담겨있던 메세지가 호출 된다.
만약 getEgg에 생긴 에러를 문제삼고 싶지않다면 (그냥 넘어가게 하고싶다면?) , getEgg 다음에 .catch에러 핸들링을 넣어줌으로써
전체적인 promise chanin에 문제가 발생하지 않도록 할 수 있다.
핸들링 도중 , 어디 부분에서 잘못됏는지 모르겟다면 바로 다음부분에 에러핸들링을 넣어보면 어떤게 문제인지 알아볼수 있을거같다.
비동기적으로 수행하고 싶은 기능들의 코드를 promise 형태로 작성하고 나서 성공 상태가 됏을 경우 resolve를 호출하게 되고
실패했다면 reject를 호출한다.
resolve 즉 성공에대한 처리방법은 .then이고 , jeject 실패에 대한 처리방법은 .catch 로 처리한다.