콜백함수에 대해서 어느정도 알았다. 그런데 콜백 지옥이라는 것이 있다. 콜백함수안에 콜백함수가 있고 그 콜백함수 안에 또 다시 콜백함수가 있는 식이다. 끊임없이 nesting되어진 함수들인데 가독성이 무지하게 떨어져서 디버깅할때 상당히 힘들다. 예제를 한 번 보자.
class UserStorage {
loginUser(id, password, onSuccess, onError) {
setTimeout(() => {
if (
(id === "yeong" && password === "5493") ||
(id === "zzak" && password == "3927")
) {
onSuccess(id);
} else {
onError(new Error("notd found"));
}
}, 2000);
}
getRoles(user, onSuccess, onError) {
setTimeout(() => {
if (user === "yeong") {
onSuccess({ name: "yeong", role: "admin" });
// console.log(onSuccess);
} else {
onError(new Error("no acess"));
// console.log(onError);
}
}, 1000);
}
}
const userStorage = new UserStorage();
// input과 비슷한게 prompt이다. alert 창 같은게 뜨면서 값을 입력하라고 한다.
const id = prompt("enter your id");
const password = prompt("enter your password");
userStorage.loginUser(
id,
password,
(user) => {
userStorage.getRoles(
// 여기서 user 는 loginUser 함수안에 있는 onSuccsess(id) 함수에 인자로 들어가는 id이다.
user,
(userWithRole) => {
alert(
`Hello ${userWithRole.name}, you have a ${userWithRole.role} role`
);
},
// 요 함수는 요렇게 나타낼 수 있다. getRoles함수 에서 함수의 인자로서 객체를 넣었다는 것을 잘 한번 생각해보자.
// function blabla(userWithRole={ name: 'yeong', role: 'admin' }) {
// alert(
// `Hello ${userWithRole.name}, you have a ${userWithRole.role} role`
// );
// }
(error) => {
console.log(error);
}
);
},
(error) => {
console.log(error);
}
);
// userstoage > onsuccess > getroles >userwithRole식으로 함수가 계속해서 nesting되는것을 callbak hell이라고 함. 가독성이 매우 떨어져 디버깅할때 애를 먹음
UserStorage란 클래스 객체를 만들고 안에 loginUser / getRoles 라는 메소드를 만들었다. 그래서 id=yeong / password=5493을 입력하면 adimn 이라는 문구가 뜨면서 잘 로그인 되었다는 로직을 만든다고 하자. loginUser 안에서 id/password를 잘 입력하면 성공했다는 함수를 콜백한다. 그리고 성공했다는 함수안에서 admin이라고 alert되는 함수를 또다시 콜백한다. 잘 동작은 한다.(참고로 여기서는 arrow 함수가 많이 쓰였다.) 근데, 이렇게 함수가 nesting되면 얼핏봐도 몇번째 인자가 어떤 인자인지 헷갈린다. 그래서 이런 코딩은 지양하는게 좋다.
그럼 어떻게 해결할 수 있을까? 바로 promise
를 사용하면 된다. 다음 글로 넘어가서 해결해보자