자바스크립트의 비동기를 돕는 객체입니다. Promise 객체를 이용하면 콜백 지옥을 방지할 수 있습니다.
function checkPositive(number, resolve, reject) {
setTimeout(() => {
if (typeof number !== "number") {
reject("주어진 값이 숫자형 값이 아님");
} else {
resolve(number > 0 ? "양수" : "음수");
}
}, 2000);
}
checkPositive(
20,
(res) => {
console.log(`성공 : ${res}`);
},
(err) => {
console.log(`실패 : ${err}`);
}
);
위 코드는 매개변수로 전달받은 number가 양수인지 음수인지 확인하는 함수입니다. 잘못된 자료형을 보내면 reject 콜백 함수를 호출하고 맞는 number 형이 들어왔을 시 양수인지 음수인지 출력합니다.
이제 이 코드를 promise를 사용하여 바꾸어보도록 하겠습니다.
function checkPositiveP(number) {
const executor = (resolve, reject) => {
setTimeout(() => {
if (typeof number !== "number") {
reject("주어진 값이 숫자형 값이 아님");
} else {
resolve(number > 0 ? "양수" : "음수");
}
}, 2000);
};
const asyncWork = new Promise(executor);
return asyncWork;
}
const result = checkPositiveP(10);
result
.then((res) => {
console.log(`작업 성공 : ${res}`);
})
.catch((err) => {
console.log(`작업 실패 : ${err}`);
});
해당 코드에서 눈 여겨볼 점은 executor 함수를 Promise 객체의 매개 변수로 담아 리턴합니다. 여기서 asyncWork의 자료형은 Promsie<any> 입니다.
promise 객체의 메서드인 then과 catch를 사용하여 resolve 함수는 then 콜백함수를, reject 함수는 catch 콜백함수를 실행하게 됩니다.
이제 전에 콜백 콜백 콜백 구조를 Promise 객체를 사용하여 바꿔보도록 하겠습니다.
function work1(a, b, cb) {
setTimeout(() => {
const result = a + b;
cb(result);
}, 3000);
}
function work2(a, cb) {
setTimeout(() => {
const result = a * 2;
cb(result);
}, 1000);
}
function work3(a, cb) {
setTimeout(() => {
const result = a * -1;
cb(result);
}, 2000);
}
work1(3, 4, (result1) => {
console.log(`work1 result = ${result1}`);
work2(result1, (result2) => {
console.log(`work2 result = ${result2}`);
work3(result2, (result3) => {
console.log(`work3 result = ${result3}`);
});
});
});
function work1(a, b) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = a + b;
resolve(result);
}, 3000);
});
}
function work2(a) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = a * 2;
resolve(result);
}, 1000);
});
}
function work3(a) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = a * -1;
resolve(result);
}, 2000);
});
}
work1(2, 3).then((result1) => {
console.log(`result1 : ${result1}`);
work2(result1).then((result2) => {
console.log(`result2 : ${result2}`);
work3(result2).then((result3) => {
console.log(`result3 : ${result3}`);
});
});
});
work1,2,3에 각각 Promise 객체를 사용하여 동일한 결과를 얻었습니다. 하지만 해당 코드는 콜백지옥과 별반 다를 바가 없습니다.
function work1(a, b) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = a + b;
resolve(result);
}, 3000);
});
}
function work2(a) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = a * 2;
resolve(result);
}, 1000);
});
}
function work3(a) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const result = a * -1;
resolve(result);
}, 2000);
});
}
work1(2, 3)
.then((result1) => {
console.log(`result1 : ${result1}`);
return work2(result1);
})
.then((result2) => {
console.log(`result2 : ${result2}`);
return work3(result2);
})
.then((result3) => {
console.log(`result3 : ${result3}`);
});
호출부를 변경하였습니다. then체이닝을 사용하여 콜백지옥을 없앴습니다. 훨씬 가독성이 좋아진 것을 확인 수 있고, 유지보수도 더 쉬워졌습니다.
해당 게시글은 인프런 강의
"한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지(이정환)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.