코드 그라데이션
콜백 지옥을 탈출하는 Promise 본문
비동기 작업이 가질 수 있는 3가지 상태
2초 뒤에 전달받은 값이 양수인지 음수인지를 판별하는 작업 만들기
function isPositive(number, resolve, reject) {
setTimeout(() => {
if(typeof number === "number") {
// 성공 -> resolve
resolve(number>=0 ? "양수" : "음수");
} else {
// 실패 -> reject
reject("숫자형 값이 아닙니다.")
}
}, 2000) //2초 대기
}
isPositive(10, // 10은 숫자형이고 양수이기 때문에 성공
(res) => {
console.log("성공적 수행 : ", res);//
},
(err) => {
console.log("실패함 : ", err);
}
);
10대신 배열을 넣어버리면
function isPositive(number, resolve, reject) {
setTimeout(() => {
if(typeof number === "number") {
// 성공 -> resolve
resolve(number>=0 ? "양수" : "음수");
} else {
// 실패 -> reject
reject("숫자형 값이 아닙니다.")
}
}, 2000) //2초 대기
}
isPositive(
[],
(res) => {
console.log("성공적 수행 : ", res);
},
(err) => {
console.log("실패함 : ", err);
}
);
이제, promise를 사용해보면?
function isPositive(number, resolve, reject) {
setTimeout(() => {
if(typeof number === "number") {
// 성공 -> resolve
resolve(number>=0 ? "양수" : "음수");
} else {
// 실패 -> reject
reject("숫자형 값이 아닙니다.")
}
}, 2000) //2초 대기
}
function isPositivePromise(number) {
const executor = (resolve, reject) => {
setTimeout(() => {
if (typeof number === "number") {
// 성공 -> resolve
console.log(number);
resolve(number >= 0 ? "양수" : "음수");
} else {
// 실패 -> reject
reject("숫자형 값이 아닙니다.");
}
}, 2000); // 0으로 수정하거나 다른 시간을 지정해주세요.
};
const asyncTask = new Promise(executor);
// 작업 자체를 실행할 변수를 만들고 여기에다가 아예 객체를 넣어줌.
}
isPositivePromise(100);
100 출력
리턴을 추가하면
이렇게 반환값을 Promise라고 볼 수가 있다.
이 뜻은 이 함수는 비동기 작업을 하고 그 결과를 프로미스 객체로 반환받아서 사용할 수 있는 함수라고 생각하면 된다.
이제 이 Promise 객체를 사용하도록 만들기
function isPositivePromise(number) {
const executor = (resolve, reject) => {
setTimeout(() => {
if (typeof number === "number") {
// 성공 -> resolve
console.log(number);
resolve(number >= 0 ? "양수" : "음수");
} else {
// 실패 -> reject
reject("숫자형 값이 아닙니다.");
}
}, 2000); // 0으로 수정하거나 다른 시간을 지정해주세요.
};
const asyncTask = new Promise(executor);
// 작업 자체를 실행할 변수를 만들고 여기에다가 아예 객체를 넣어줌.
return asyncTask; // 리턴을 추가
}
// 사용하기
const res = isPositivePromise(100);
res.then((res) => {
console.log("작업 성공 : ", res);
})
.catch((err) => {
console.log("작업 실패 : ", err);
});
이제, 콜백 지옥 탈출하기
저번 포스팅에서 작성했던 함수 다시 가져와서 바꾸기
기존 코드
function taskA(a, b, callback) { // 파라미터와 콜백함수 추가
setTimeout(() => {
const res = a + b;
callback(res);
}, 3000); // 3초 대기
}
function taskB(a, callback) {
setTimeout(() => {
const res = a * 2;
callback(res);
}, 1000); // 1초 대기
}
function taskC(a, callback) { // 파라미터와 콜백함수 추가
setTimeout(() => {
const res = a * -1;
callback(res);
}, 2000); // 2초 대기
}
taskA(3, 4, (a_res) => { //
console.log("A Result : ", a_res);
taskB(a_res, (b_res) => {
console.log("B Result : ", b_res);
taskC(b_res, (c_res) => {
console.log("C Result : ", c_res);
})
})
});
이걸 바꾸는데
function taskA(a, b) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const res = a + b;
resolve(res);
}, 3000); // 3초 대기
});
}
function taskB(a) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const res = a * 2;
resolve(res);
}, 1000); // 1초 대기
})
}
function taskC(a) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const res = a * -1;
callback(res);
}, 2000); // 2초 대기
})
}
// 이제 저 아래처럼 콜백을 계속 하지 말고 promise 객체 결과값을 그대로 쓰자
taskA(5, 1).then((a_res) => {
console.log("A RESULT : ", a_res);
taskB(a_res).then((b_res) => {
console.log("B RESULT : ", b_res);
taskC(b_res).then((c_res) => {
console.log("C RESULT : ", c_res);
});
});
});
// 이제 저 아래처럼 콜백을 계속 하지 말고 promise 객체 결과값을 그대로 쓰자
taskA(5, 1).then((a_res) => {
console.log("A RESULT : ", a_res);
taskB(a_res).then((b_res) => {
console.log("B RESULT : ", b_res);
taskC(b_res).then((c_res) => {
console.log("C RESULT : ", c_res);
});
});
});
이것도 크게 달라진 거 같진 않다...
사용 방법이 잘못되었다.
이렇게 쓰는 게 사실 맞다.
이어가면
이렇게 then 메서드를 계속 이어붙이는 것을 then chaining이라고 부른다.
모양을 확실히 비교하면 다르더라
Promise 객체를 이용하면 이렇게 중간에 끼워넣기도 얼마든지 수월하다
728x90
'Front > Mega-JavaScript' 카테고리의 다른 글
API 호출하기 (0) | 2024.04.14 |
---|---|
async, await (0) | 2024.04.13 |
동기와 비동기 (0) | 2024.04.12 |
조건문 업그레이드 (0) | 2024.04.11 |
단락회로 평가 (0) | 2024.04.11 |
Comments