우선 콜백이 무엇인지 헷갈리시는 분은 아랫글을 참고해주세요
https://ethereal-coder.tistory.com/32
[JavaScript] 콜백함수
콜백함수는 함수를 매개변수로 받는 함수이다. 예시 코드 function day(time, morning, night){ if(time === "morning"){ morning(); //wakeUp이 출력 } else{ night(); //goToSchool이 출력 } } function wakeUp(){ console.log("wakeUp"); } f
ethereal-coder.tistory.com
Promise는 정말 자바스크립트를 공부하면서 고비라고 생각할 정도로 어려웠다.
강의 영상을 정말 5번 정도 돌려봤는데도 이해가 안돼서 앞에 내용을 더 단단하게 이해하고 오니 바로 어느정도 습득했다!
혹시 promise가 너무 어렵다고 생각하시는 분들은 콜백지옥의 코드를 정확히 이해하고 다시 보는 것을 추천한다.
콜백지옥
function taskA(a,b,cb){
setTimeout(() => {
const res = a+b;
cb(res);
},3000);
}
function taskB(a,cb){
setTimeout(() => {
const res = a *2 ;
cb(res);
},3000);
}
function taskC(a,cb){
setTimeout(() => {
const res = a * 5;
cb(res);
},3000);
}
//호출하기
//2와 3을 더하고, 여기에 2를 곱하고, 5를 곱하도록 호출하기
taskA(2,3,(a_res) = >{
console.log(a_res); // 2+3 출력
taskB(a_res,(b_res) => {
console.log(b_res); //(2+3) *2 출력
taskC(b_res,(c_res) => {
console.log(c_res); // (2+3)*2*5 출력
});
});
});
console.log("코드끝");
위 코드는 비동기적 함수가 있으므로, 코드 끝이 먼저 출력되고 나머지 것들이 차례로 출력된다.
위와 같이 비동기함수의 리턴 값을 또 다른 비동기 함수에 전달하고 또 전달하고를 반복하면 콜백지옥에 걸린다. 이를 구원하기 위한 것이 promise이다.
Promise
비동기 함수가 가질 수 있는 상태는 세가지이다.
- Pending (대기상태)
- Fulfilled (성공)
- Rejected (실패)
대기상태에서 함수가 정상적으로 실행되면 성공, 아니면 실패이다.
여기서 함수가 성공한 것을 resolve되었다 라고 하고 , 실패한 것을 reject 되었다고 한다.
우선, 콜백함수만을 사용해서 받은 값이 양수인지, 음수인지 판단하는 코드를 만들었다.
function isPostive(number, resolve, reject){
setTimeout(()=> {
if(typeof number === "number"){
//성공(resolve했을 때라고 가정)
resolve(number >= 0 ? "양수" : "음수");
}
else{
//실패(reject 했을 때라고 가정)
reject("값이 잘못 입력되었습니다.");
}
},2000);
}
isPostive(
5,
(res) => {
console.log("성공 : ", res);
},
(err) => {
console.log("실패 : ",err);
}
);
이를 promise객체를 이용해서 다시 작성해보면
function isPostive(number){
const exeutor = (resolve, reject) => {
setTimeout(()=> {
if(typeof number === "number"){
//성공(resolve했을 때라고 가정)
resolve(number >= 0 ? "양수" : "음수");
}
else{
reject("값이 잘못 입력되었습니다.");
}
},2000);
};
const tesk = new Promise(exeutor); //isPositive호출되면 바로 여기로
return tesk;
}
const res = isPostive( 100 ); // number을 넣은 객체를 반환
res.then((res) =>{
console.log("성공 : ",res);
}
).catch((err) =>{
console.log("실패 :", err);
})
이렇게 된다. res에 isPositive를 호출하여 isPositive 내에 함수를 promise에 넣어 리턴한 값을 받고,
res.then(성공했을 때 함수).catch(실패했을 때 함수) 로 호출하면 위와 같은 기능을 하는 코드가 만들어진다.
그럼, 글 위쪽에서 콜백지옥을 설명했던 코드를 promise를 이용해서 짜보자.
function taskA(a){
return new Promise((resolve,reject) => {// promise 객체 리턴
setTimeout(() => {
const res = a+b;
resolve(res);
},3000);
});
}
function taskB(a){
return new Promise((resolve,reject) => {// promise 객체 리턴
setTimeout(() => {
const res = a *2 ;
resolve(res);
},3000);
});
}
function taskC(a){
return new Promise((resolve,reject) => {// promise 객체 리턴
setTimeout(() => {
const res = a * 5;
resolve(res);
},3000);
});
}
taskA(2,3) //taskA의 promise 리턴됨
.then((a_res) => {
console.log("A result : ",a_res);
return taskB(a_res);
}) //taskB의 promise 리턴됨
.then((b_res) => {
console.log("B result : ",b_res);
return taskC(b_res);
}) //taskC의 promise 리턴됨
.then((c_res) =>{
console.log("C result", c_res);
})
위에 있는 task들은 매개변수로 하나의 정수로 만들고, promise객체를 리턴하도록 한다.
또한 호출하는 부분은 위와 같이 promise객체가 리턴될 때마다 then 을 이용해서 다음에 실행할 함수를 만들어준다. 이때 then이 여러개라 어색하다고 느낄 수 있는데, 주석 친 부분에서 promise 객체가 리턴되고 then은 이 각각의 객체에 대한 것이니까 문제가 없는 코드이다.
이런 방식으로 코드를 짜면, 가독성이 높아진다는 장점도 있지만,
const task = taskA(2,3) //상수를 만들어 여기다가 promise객체 받음
.then((a_res) => {
console.log("A result : ",a_res);
return taskB(a_res);
});
console.log("안녕하세요"); // 다른코드
task.then((b_res) => { //위에서 받은 promise객체에 then으로 호출
console.log("B result : ",b_res);
return taskC(b_res);
})
.then((c_res) =>{
console.log("C result", c_res);
})
위의 코드처럼 콜백 함수들을 실행하는 중간에 다른 코드를 넣을 수 있다는 장점이 있다.
'Front-end > javascript' 카테고리의 다른 글
[JavaScript] API 호출 (0) | 2023.07.30 |
---|---|
[JavaScript] async와 await (0) | 2023.07.28 |
[JavaScript] 동기, 비동기 (1) | 2023.07.18 |
[JavaScript] spread 연산자 (0) | 2023.07.17 |
[JavaScript] 비 구조화 할당 (1) | 2023.07.17 |