Callback Hell (콜백 지옥)
32511 단어 TILpromisecallbackjavascirptTIL
콜백 함수(Callback function)
콜백함수는 다른 함수에 매개변수로 넘겨준 함수를 말한다. 함수를 명시적으로 호출하는 방식이 아니라 특정 이벤트가 발생했을 때 시스템에 의해 호출된다.
- 콜백이란 다른 함수(A)의 전달인자(argument)로 넘겨주는 함수(B)를 말한다.
- 매개변수를 넘겨 받은 함수(A)는 callback 함수(B)를 필요에 따라 즉시 실행(synchronously) 할 수도 있고, 아니면 나중에 (asynchronously) 실행할 수도 있다.
- CallBack
콜백 지옥(Callback Hell)
콜백 지옥은 JavaScript를 이용한 비동기 프로그래밍시 발생하는 문제로서, 함수의 매개 변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상을 말한다.
-
주로 이벤트 처리나 서버 통신과 같은 비동기적인 작업을 수행하기 위해 이런 형태가 자주 등장하는데, 이와 같은 코드는 가독성이 떨어지고, 코드를 수정하기 어려워 진다.
-
예시 ▼
step1(function (value1) {
step2(function (value2) {
step3(function (value3) {
step4(function (value4) {
step5(function (value5) {
step6(function (value6) {
// Do something with value6
});
});
});
});
});
});
- step1에서 어떤 처리 이후 그 결과를 받아와, 인자로 전달된 익명 함수의 매개변수로 넘겨준다. 이후 step2에서 또 어떤 처리를 하고, 다음 익명 함수가 실행된다. 이를 반복하다보면 코드가 피라미드 모양으로 기술되게 된다.
콜백지옥 예제
- 사용자 데이터를 백엔드(서버)에서 받아오는 클래스를 만든다고 가정한다.
class UserStorage{
loginUser(id, password, onSuccess, onError){
setTimeout(() =>{
if(
(id === 'seul' && password === '123') ||
(id === 'kim' && password === '456')
) {
onSuccess(id);
} else{
onError(new Error('error'));
}
}, 2000);
}
getRoles(user, onSuccess, onError){
setTimeout(()=> {
if (user === 'seul') {
onSuccess({name: 'seul', role: 'admin'});
} else {
onError(new Error('error'));
}
}, 1000);
}
};
const userStorage = new UserStorage();
const id = prompt('아이디를 입력해 주세요!');
const password = prompt('비밀번호를 입력해 주세요!!');
userStorage.loginUser(
id,
password,
user => {
userStorage.getRoles(
user,
userWithRole => {
alert(`hello ${userWithRole.name}, you have a ${userWithRole.role} role`)
},
error => {
console.log('에러2')
}
);
},
error => {console.log('에러1')}
);
1. promise 를 활용해서 콜백지옥 탈출하기
class UserStorage{
loginUser(id, password){
return new Promise((resolve, reject) => {
setTimeout(() =>{
if(
(id === 'seul' && password === '123') ||
(id === 'kim' && password === '456')
) {
resolve(id);
} else{
reject(new Error('에러1'));
}
}, 2000);
})
}
getRoles(user){
return new Promise((resolve, reject) => {
setTimeout(()=> {
if (user === 'seul') {
resolve({name: 'seul', role: 'admin'});
} else {
reject(new Error('에러2'));
}
}, 1000);
})
}
};
const userStorage = new UserStorage();
const id = prompt('아이디를 입력해 주세요!');
const password = prompt('비밀번호를 입력해 주세요!!');
userStorage.loginUser(id, password)
.then(userStorage.getRoles)
// .then(user => userStorage.getRoles(user)); 인자가 똑같으니 생략 가능하다.
.then(user => alert(`hello ${user.name}, you have a ${user.role} role`))
.catch(console.log);
- 1) userStorage에서 로그인을 한다.
- 2) 로그인이 성공하면 user가 전달되므로 전달된 user를 이용해서 getRoles,를 호출한다.
- 3) getRoles 까지 성공적으로 수행 된다면 최종적으로 받아온 user를 이용해서 alert창을 나타낸다.
- 모두 성공적으로 마쳤을 때 결과와, 도중에 실패했을 때▼
- 마지막행의 .catch(console.log); 를 작성하지 않고 에러가 발생했을 때 ▼
2. async & await 적용하기
class UserStorage{
loginUser(id, password){
return new Promise((resolve, reject) => {
setTimeout(() => {
if(
(id === 'seul' && password === '123') ||
(id === 'kim' && password === '456')
) {
resolve(id);
} else{
reject(new Error('에러1'));
}
}, 2000);
})
}
getRoles(user){
return new Promise((resolve, reject) => {
setTimeout(()=> {
if (user === 'seul') {
resolve({name: 'seul', role: 'admin'});
} else {
reject(new Error('에러2'));
}
}, 1000);
})
}
};
const userStorage = new UserStorage();
const id = prompt("아이디를 입력해 주세요!");
const password = prompt("비밀번호를 입력해 주세요!!");
async function checkUser() {
try {
const userId = await userStorage.loginUser(id, password);
const user = await userStorage.getRoles(userId);
alert(`Hello ${user.name}, you have a ${user.role}`);
} catch (error) {
console.log(error);
}
}
checkUser();
📌 try...catch
try...catch
문은 실행할 코드블럭을 표시하고 예외(exception)가 발생(throw)할 경우의 응답을 지정한다.- MDN_try...catch
try {
nonExistentFunction();
} catch (error) {
console.error(error);
}
✍️ 다른 콜백 예제들도 접해보고, 코드가 점점 복잡해지는 이유와 promise 혹은 async & await를 활용해서 어떻게 콜백지옥을 벗어날 수 있는지 보면서 더 익숙해져야 겠다.
HANAMON-callback
yujo-callback
librewiki
dream-coding
Author And Source
이 문제에 관하여(Callback Hell (콜백 지옥)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@seul06/JavaScript-콜백-지옥저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)