Promise를 이해하기 전 알아야할 callback 함수 / Callback hell, 콜백함수의 지옥 etc. ↓↓
----------------------------------------------------------------------------------------------------------------------------------
Promise
그 유명한.... Callback Hell
콜백함수의 지옥 현상을 극복했다는 평을 받는 promise, 반드시 알아두어야 하는 객체!
/* Promise basic code frame */
const 변수 = new Promise((resolve, reject)=>{
resolve()-> resolve를 매개변수로 갖는 콜백함수
reject() -> reject를 매개변수로 갖는 콜백함수
})
콜백의 반환 값을 한 객체에 담음
new 가 쓰인다는 건 - > 결과값이 Object, 객체이다.
Promise((첫 번째 속성, 두 번째 속성)=> {})
첫 번째 속성 - state
두 번째 속성 - reject -> 요 속성값들의 위치는 정해진 것
이동통신(?) | state | result |
대기 상태 | pending | undefined |
성공 시 | fulfilled | " " (이 값은 우리가 정함) |
실패 시 | rejected | " " (요 result 값도 우리가 정함) |
---------------------------------------------------------------------------------------------------------------------------------
잘 이해가 안가서 하나하나 비교해보기
condition = true 일 때,
const condition = true; // true면 resolve 가 실행, false면 rejecte이 실행된다.
const pr = new Promise((resolve, reject)=>{
if(condition){
resolve('성공!');
} else {
reject('실패!')
}
})
true 의 경우 첫 번째 인자 resolve 가 실행된다.
객체에 '성공' 이라는 글자를 넘겨줌
condition = false; 일 때,
const condition = false;
const pr = new Promise((resolve, reject)=>{
if(condition){
resolve('성공!');
} else {
reject('실패!')
}
})
false의 경우 두 번째 인자 reject 가 실행된다.
객체에 '실패' 라는 글자를 넘겨줌
----------------------------------------------------------------------------------------------------------------------------------
promise 객체 안 함수들 이용해보기
pr을 console.log에 쳐서 __proto__ 안을 보면 사용할 수 있는 함수들이 나온다. 그 중에 많이 사용하는
pr.then()
pr.catch()
pr.finally() 를 사용해보기
.then( )
When Promise status = fulfilled
Promise 내부에서 resolve가 호출되면 (즉, 성공하면) then의 message 가 '성공!'이 된다.
const pr = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('성공!');
},1000)
})
pr.then((message)=>{
console.log(message);
})
.then( ) 인자값에 callback 함수가 들어감.
첫 번째 인자값에는 new 객체의 resolve 성공의 result값을 반환함. ** 중요**
message 라는 반환받을 변수명을 지정해 줌.
.catch( )
When Promise status = rejected
Promise 내부에서 reject 가 호출되면 (실패하면) catch의 error가 '실패!' 가 된다.
const pr = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject('실패!');
},1000)
})
pr.catch((error)=>{
console.log(error);
})
.catch( )
첫 번째 인자값에 new 객체의 reject 실패의 반환값 '실패!' 를 반환한다.
질문4 Uncaught (in promise) 실패 ! -> ?
.then( ) + .catch( ) 함께 쓰기 ( then()의 뒤에 .catch를 쓴다. )
const pr = new Promise((resolve,reject)=>{
setTimeout(()=>{ //setTimeout( ()=>{}, 1000) 1초뒤에 ()=>{}요 함수 실행!
reject('실패!');
},1000)
})
pr.then((message)=>{ //resolve 인 경우
console.log(message);
}).catch((error)=>{ // reject 인 경우
console.log(error);
})
.finally ( )
가장 마지막에 쓰는 성공/실패 여부와 상관없이 무조건 실행됨.
const pr = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('성 - 공 !');
},1000)
})
pr.then((message)=>{
console.log(message);
}).catch((error)=>{
console.log(error);
}).finally(()=>{
console.log('내가 finally다.')
})
setTimeout 빼고 / resolve, reject 둘 다 써보기
const pr = new Promise((resolve,reject)=>{
resolve('성 - 공 !');
reject('실 - 패 !');
})
pr.then((message)=>{
console.log(message);
}).catch((error)=>{
console.log(error);
}).finally(()=>{
console.log('내가 finally다.')
})
resolve만 실행된다.
-------------------------------------------------여기까지 Promise 정리해보기 -----------------------------------------------
Callback Hell 의 불편함 해소를 위해 Promise 등장
const pr = new Promise ((resolve, reject)=>{
resolve('성공입니다!');
})
resolve - 성공 시, reject -> 실패 시. resolve('성공입니다!') 이므로 resolve = 성공 = fulfilled (status)
pr이라는 변수에 객체로 반환 된 값이 담김
Promise { <fulfilled> : "성공입니다!" }
const pr = new Promise ((resolve, reject)=>{
resolve('성공입니다!');
})
pr.then((message)=>{
console.log(message);
}).catch((error)=>{
console.log(error);
}).finally(()=>{
console.log('Finally the end')
})
객체로 담긴 pr의 값 = > Promise { <fulfilled> : "성공입니다!" } 에 성공이면
.then 인자값으로 받은 '성공입니다'를 console.log에 출력
.catch 오류 안났으니 pass
.fianlly 는 무조건 실행하니 'Finally the end' logged
------------------------------------------------------------------------------------------------------------------------------
1. 변수 아반떼에 new Promise 객체의 반환 값 담기
아반떼 = new Promise resolve(fulfilled의) 값 "아반떼 지나갑니다.' 을 담는다.
아반떼 = {<fulfilled> : '아반떼 지나갑니다' }
const 아반떼 =
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('아반ㄸㅔ 지나갑니다.');
},3000)
})
2. 변수 아반떼에 함수 new Promise 값 이다. 라고 쓴 것 -> 아반떼() 값으로 출력 x -> return 이 필요
변수 아반떼는 = { promise { <fulfilled : '아반떼 지나갑니다' } } 이다.
const 아반떼 =()=>{
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('아반ㄸㅔ 지나갑니다.');
},3000)
})
}
3. 변수 아반떼에 new Promise 객체로 반환한 값을 출력하는 함수
아반떼 = return 반환해라 new Promise 객체로 받은 값을
const 아반떼 = ()=> {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('아반ㄸㅔ 지나갑니다.');
},3000)
})
}
질문5 왜 pending ? ?
--------------------------------------------------------------------------------------------------------------------------------
Promise Chain
promise 객체 3개 만들어 놓기
const 아반떼 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('아반떼 갑ㄴ ㅣㄷ ㅏ ');
},3000)
})
}
const 소나타 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('소나타 지나갑ㄴ ㅣㄷ ㅏ ');
},2000)
})
}
const 그랜저 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('그랜 져 갑ㄴ ㅣㄷ ㅏ ');
},1000)
})
}
아반떼().then((result)=>{
console.log(result);
})
Promise chain 완성
const 아반떼 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('아반떼 갑ㄴ ㅣㄷ ㅏ ');
},3000)
})
}
const 소나타 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('소나타 지나갑ㄴ ㅣㄷ ㅏ ');
},2000)
})
}
const 그랜저 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('그랜 져 갑ㄴ ㅣㄷ ㅏ ');
},1000)
})
}
아반떼().then((result)=>{
console.log(result);
return 소나타();
}).then((result)=>{
console.log(result);
return 그랜저();
}).then((result)=>{
console.log(result);
})
소나타의 값을 reject로 바꿈 -> 아래 .catch로 변경
const 아반떼 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('아반떼 갑ㄴ ㅣㄷ ㅏ ');
},3000)
})
}
const 소나타 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
reject('소나타 이번에 쉽니다.');
},2000)
})
}
const 그랜저 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('그랜 져 갑ㄴ ㅣㄷ ㅏ ');
},1000)
})
}
아반떼().then((result)=>{
console.log(result);
return 소나타();
}).catch((error)=>{
console.log(error);
return 그랜저();
}).then((result)=>{
console.log(result);
})
질문6 : 두 개가 같은 건지
아반떼().then((result)=>{
console.log(result);
소나타().then((result)=>{
console.log(result);
그랜저().then((result)=>{
console.log(result);
})
})
})
아반떼().then((result)=>{
console.log(result);
return 소나타();
}).then((result)=>{
console.log(result);
return 그랜저();
}).then((result)=>{
console.log(result);
})
------이렇게 쓰면 에러가 나는 이유 ?
아반떼().then((result)=>{
console.log(result);
return 소나타();
}).catch((error)=>{
console.log(error);
return 그랜저();
}).then((result)=>{
console.log(result);
}).fianlly(()=>{
console.log('- 경주 끗 -')
})
return -> 값을 반환
function sum(a,b) {
return a+b;
}
let plus = sum(1,2);
console.log(plus)
이것저것 수정해보기
const 아반떼 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('아반떼 갑ㄴ ㅣㄷ ㅏ ');
},3000)
})
}
const 소나타 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
reject('소나타 쉽니ㄷr.');
},2000)
})
}
const 그랜저 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('그랜 져 갑ㄴ ㅣㄷ ㅏ ');
},1000)
})
}
아반떼().then((result)=>{ // 1. resolve이므로 then 실행ok
console.log(result);
return 소나타(); //소나타 -> reject
}).then((result)=>{ //result -> 없음
console.log(result);
return 그랜저();
}).then((result)=>{
console.log(result);
}).catch((error)=>{ // 2. catch 실패로 넘어옴
console.log(error+' 잡았다 요놈'); //출력
}).finally(()=>{
console.log('끗'); // 3. 성공실패 관계없이 finally 출력
})
const 아반떼 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('아반떼 갑ㄴ ㅣㄷ ㅏ ');
},3000)
})
}
const 소나타 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
reject('소나타 쉽니ㄷr.');
},2000)
})
}
const 그랜저 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('그랜 져 갑ㄴ ㅣㄷ ㅏ ');
},1000)
})
}
아반떼().then((result)=>{
console.log(result);
return 소나타(); //소나타()의 값이 넘어감 = rejected
}).catch((error)=>{ //catch 맞으니 error에 reject 값 '소나타쉽니다'입력됨
console.log(error); //'소나타 쉽니다' 출력
return 그랜저();
}).then((result)=>{
console.log(result);
}).catch((error)=>{ //에러난게 없으므로 pass
console.log(error+' 잡았다 요놈');
}).finally(()=>{ //항상 출력
console.log('끗');
})
console.time('xxx') 으로 시간 재기
const 아반떼 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('아반떼 갑ㄴ ㅣㄷ ㅏ ');
},3000)
})
}
const 소나타 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('소나타 다시 갑니ㄷr.');
},2000)
})
}
const 그랜저 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('그랜 져 갑ㄴ ㅣㄷ ㅏ ');
},1000)
})
}
console.time('record');
아반떼().then((result)=>{
console.log(result);
return 소나타(); //소나타()의 값이 넘어감 = rejected
}).then((result)=>{ //catch 맞으니 error에 reject 값 '소나타쉽니다'입력됨
console.log(result); //'소나타 쉽니다' 출력
return 그랜저();
}).then((result)=>{
console.log(result);
}).catch((error)=>{ //에러난게 없으므로 pass
console.log(error+' 잡았다 요놈');
}).finally(()=>{ //항상 출력
console.log('끗');
console.timeEnd('record')
})
-> 여기까지가 Promise Chain
단점 : 하나의 결과값만 가지고 싶은데 하나하나 계속 해야함
한번에 처리 방법 -> Promise all
Promise all
한번에 배열로 넣어 처리하는 Promise all
const 아반떼 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('아반떼 갑ㄴ ㅣㄷ ㅏ ');
},3000)
})
}
const 소나타 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('소나타 다시 갑니ㄷr.');
},2000)
})
}
const 그랜저 = () => {
return new Promise ((resolve, reject)=>{
setTimeout(()=>{
resolve('그랜 져 갑ㄴ ㅣㄷ ㅏ ');
},1000)
})
}
Promise.all([아반떼(),소나타(),그랜저()]).then((result)=>{
console.log(result);
})
배열로 한번에 처리가 된다. 시간도 단축 되었다.
console.time 찍어보기
console.time('record')
Promise.all([아반떼(), 소나타(), 그랜저()]).then((result)=>{
console.log(result);
console.timeEnd('record')
})
각각 요청을 한번에 동시다발적으로 처리하는 비동기 식으로 진행되는걸 알 수 있다!
콜백 지옥을 해결하기 위해 생겼지만 그래도 코드가 조금 복잡(?) 하다고 느껴져서 또 새롭게 생긴 아이
async가 있다.
async 포스팅 보러가기 ↘