FE/JavaScript
[JavaScript] 콜백 지옥 (2)
m5n
2024. 10. 16. 22:52
Promise 객체의 등장
- 문제점
- 기존 콜백함수의 경우, 중첩해서 사용하게 되면 가독성이 매우 떨어짐 (콜백 지옥)
- 좀 더 가독성이 좋은 방법은 없을까 ? -> Promise 객체의 등장
- 특징
- resolve, reject 함수를 인자로 갖는 함수를 인자로 가짐
- then의 return 값 또한 Promise 객체임
- resolve
- 조건이 성공되었을 때 반환하는 콜백함수
- then에서 전달해준 함수가 들어감
- reject
- 조건이 실패하였을 때 반환하는 콜백함수
- catch에서 전달해준 함수가 들어감
// Resolve - 성공했을 때 반환하는 콜백함수
// reject - 실패했을 때 반환하는 콜백함수
// then 함수의 인자는 여기서 1개 -> 데이터 타입이 함수 -> 그 함수의 인자가 data
// then에서 전달해준 함수가 resolve로 들어감.
// ** then 메소드의 호출 결과는 프로미스 객체임 **
// catch는 reject로 들어가고
// finally는 then이든 catch든 리턴된 놈이 들어감
new Promise((resolve, reject) => {
if(1) {
const value = 10;
resolve(value);
} else {
const error = new Error('에러발생')
reject(error);
}
}).then(data => {
console.log(data)
}).catch(err => {
console.log(err)
}).finally(() => {
console.log("종료")
})
Promise 객체의 이용
- 가독성
- runTask() 함수를 보면 이전 글의 콜백 지옥보다 가독성이 좋아진 것을 확인 가능함
- 하지만 아직 익숙하지가 않음 ... -> 원래 쓰던 문법처럼 사용할 순 없을까 ?
- async, await 키워드의 등장
// 1초 후에 실행하는 fastFunction, 데이터에 2를 곱함
function fastFunction(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = data * 2;
console.log("fast function done", result)
resolve(result);
}, 1000)
})
}
// 3초 후에 실행하는 slowFunction, 데이터에 10을 더함
function slowFunction(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = data + 10;
console.log("slow fucntion done", result)
resolve(result);
}, 3000)
})
}
// 2초 후에 실행하는 normalFunction, 데이터 2로 나눔
function normalFunction(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = data / 2;
console.log("normal function", result)
resolve(result);
}, 2000)
})
}
// 예제
// slow->fast->normal->slow
function runTasks() {
slowFunction(10).then((data) => { // then의 인자가 reslove로 들어간다. then의 리턴 값도 promise 객체다
return fastFunction(data);
}).then((data) => {
return normalFunction(data);
}).then((data) => {
return slowFunction(data); // 더이상 인자로 받은 reslove()가 없음 (.then이 없으니까)
}).finally(() => { // -> finally()가 실행됨
console.log("end");
})
}
runTasks()