[ Javascript ] - Promise then / catch

슬로그·2023년 6월 29일
0

JS

목록 보기
5/7
post-thumbnail

프로미스의 상태 (state)
1. 수행중일 때 -> pending 상태
2. 수행이 다끝나면 -> fulfilled 상태
3. 에러가 난다면 -> rejected 상태

Promise 는
정보를 제공하는 producer
정보를 소비하는 consumer
로 나누어 진다.

1. producer

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-1) 두가지의 콜백함수를 받을수 있다.

1. resolve : 기능을 정상적으로 수행해서 마지막 최종 데이터를 전달
2. reject : 기능을 수행하다가 중간에 문제가 생기면 호출

* 유의할점
새로운 promise가 만들어 질때는 전달한 ececutor(resolve, reject) 함수가 자동적으로 바로 실행이 되는데,
예를 들어 클릭후에 데이터를 요청해야하는 경우에는 promise에 대해 다시 생각을 해볼 필요가 있다.

1-2) 데이터 받기 성공 상태 : resolve

성공적으로 네트워크 또는 파일에서 읽어온 사용자를 받아왔을 경우 resolve를 호출하면서 bosule값을 전달해준다.

1-3) 데이터 받기 error 상태 : reject

resolve 대신 reject를 호출할경우 에러 메세지 발생

2. Consumer : then, catch , finally

promise
  	2-1)
    .then((value) =>{
	 	console.log(value);	 // 2초 뒤에 bosule 출력 
	})
	2-2)
    .catch((error) =>{
  		console.log(error);
  	})
	2-3)
    .finally(() =>{
		console.log('finally');
    })

2-1) resolve 상태 .then 으로 처리하기

값이 정상적으로 잘 수행이 되어서 resolve 상태가 된다면 callback 함수에서 전달된 위에 bosule 이라는 값이 들어오게 된다.

2-2) reject 상태 .catch 로 처리하기

에러 reject가 발생했을때 어떻게 처리할건지 callback 함수를 작성 
예시에서는 에러 메세지 를 콘솔로 출력할 수 있도록 설정

2-2) 성공 / 실패와 상관없이 호출 .finally

.finally 작성 시 성공 됏을경우에도 호출 되고 실패했을 경우에도 호출
어떤기능을 마지막으로 수행하고 싶을때 사용

3. Promise chaining

	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를 전달할수도 있다. 

4. 코드로 이해해보기

	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))

4-1) 코드 해석해보기

어렵다고 느껴졌는데 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)

5. Error Handling

	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))

5-1) error 핸들링 하기

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 로 처리한다.

profile
빨리가는 유일한 방법은 제대로 가는것

0개의 댓글