728x90
자바스크립트에서 비동기 처리를 위해
Promise와 Callback 함수가 자주 등장하는데,
Promise의 사용을 Callback 사용보다 더 권장하는 이유는
코드가 훨씬 간결해져 가독성이 좋아지기 때문이다.
샘플 예제 ↓
샘플 예제로 간단한 로그인을 구현하는 스크립트 예제를 만들어 보았다.
간단하게 아이디, 비밀번호를 물어보고,
아이디와 비밀번호가 맞으면, 회원등급을 조회 후
메일을 발송하는 예제이다.
서버 측 처리는 setTimeOut을 통해 딜레이를 설정하였다.
[Javascript : Callback함수 사용]
//사용자 로그인 예제 :by Callback
class Login { //로그인 객체
logUser(id,pw,onSuccess,onError){
setTimeout(() => {
//로그인
if(id==='gildong' && pw === '1234'){
onSuccess(id);
}else{
onError(new Error('아이디와 비밀번호를 확인해주세요'));
}
}, 2000);
}
getRoles(id, pw, onSuccess, onError){
setTimeout(() => {
if(id === 'gildong' && pw === '1234'){
onSuccess(id);
}else{
onError(new Error(`${id}님은 등급이 존재하지 않습니다.`));
}
}, 1500);
//등급 조회
}
sendEmail(id, pw, emailAddress, onSuccess, onError){
setTimeout(()=>{
if(id === 'gildong' && pw === '1234'){
onSuccess(emailAddress);
}else{
onError(new Error(`이메일을 보낼수 없습니다.`));
}
},2000);
}
writeContents(emailAddress, onSuccess){
setTimeout(() => {
prompt('내용을 입력해주세요');
onSuccess(emailAddress);
}, 1000);
}
}
//로그인
const userInfo = new Login();
const id = prompt('아이디를 입력 해주세요.');
const pw = prompt('비밀번호를 입력 해주세요.');
userInfo.logUser(
id,
pw,
(user)=>{ //onSuccess
console.log(`${user}님 환영합니다.`);
userInfo.getRoles(
id,
pw,
(user)=>{ //onSuccess
console.log(`${user}님의 등급은 Green 등급입니다`);
if(confirm('이메일을 보내시겠습니까?')){
const mailAddress = prompt('보내실 Email 주소를 작성해주세요');
userInfo.sendEmail(
id,
pw,
mailAddress,
(mailAddress)=>{ //onSuccess
userInfo.writeContents(
mailAddress,
(add)=>{
alert(`${add}님께 메일 발송 완료`);
});
},
(errMsg)=>{ //onError
console.log(errMsg);
});
} else {
alert('로그아웃 하였습니다.');
}
},
(errMsg)=>{ //onError
console.log(errMsg);
});
},
(err)=>{ //getRoles
console.log(err);
});
위 코드를 보면, Callback 함수로 인해
코드의 가독성이 얼마나 떨어지는지 알수 있는데,
'이를 콜백 지옥이라고 부르기도한다'
[콜백지옥 예시]
() => { () => { () => { ()=>{ ()=>{ ()=>{ ()=>{ } } } } } } } |
위와같은 콜백지옥을 해결할수 있는 방법이
Promise()인데, 위의 예제를 하단에 Promise를 사용한 예로 바꿔 보았다.
[Javascript : Promise() 사용]
//사용자 로그인 예제 :by Callback
class Login { //로그인 객체
logUser(id, pw){
//로그인
return new Promise((resolve,reject)=>{
setTimeout(() => {
if(id==='gildong' && pw === '1234'){
resolve(id);
}else{
reject(new Error('아이디와 비밀번호를 확인해주세요'));
}
}, 2000);
});
}
getRoles(id, pw){
//등급 조회
return new Promise((resolve,reject)=>{
setTimeout(() => {
if(id === 'gildong' && pw === '1234'){
resolve(id);
}else{
reject(new Error(`${id}님은 등급이 존재하지 않습니다.`));
}
}, 1500);
});
}
sendEmail(id, pw, emailAddress){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
if(id === 'gildong' && pw === '1234'){
resolve(emailAddress);
}else{
reject(new Error(`이메일을 보낼수 없습니다.`));
}
},2000);
});
}
writeContents(emailAddress){
return new Promise((resolve)=>{
setTimeout(() => {
prompt('내용을 입력해주세요');
resolve(emailAddress);
}, 1000);
});
}
}
//로그인
const userInfo = new Login();
const id = prompt('아이디를 입력 해주세요.');
const pw = prompt('비밀번호를 입력 해주세요.');
userInfo.logUser(id,pw)
.then(user => {
console.log(`${user}님 환영합니다.`);
userInfo.getRoles(id,pw)
.then(userId=>{
console.log(`${userId}님의 등급은 Green 등급입니다`);
if(confirm('이메일을 보내시겠습니까?')){
const mailAddress = prompt('보내실 Email 주소를 입력하세요');
userInfo.sendEmail(id,pw,mailAddress)
.then(mail=>{
userInfo.writeContents(mail)
.then(sendUser=>alert(`${sendUser}님께 발송 완료`));
})
.catch(console.log);
}
})
.catch(console.log)
})
.catch(console.log);
예외처리까지 그전 코드와는 확연히 차이가 난다.
사실 싱글스레드로 구동되는 자바스크립트라는 언어 내에서
실제 구동되는 내부 로직의 효율성 그 자체는 모르긴 몰라도 별차이 없을수 있다.
하지만 깔끔함이 갖추어진 간결한 코드는
사람이 하는 유지보수나 개발의 효율을 훨씬 높일수 있다.
728x90
'프론트엔드 > Javascript' 카테고리의 다른 글
[Javascript] 배열 Array API - join() (0) | 2021.02.09 |
---|---|
[Javascript] Promise - then 체이닝시 유의사항 (0) | 2021.02.08 |
[Javascript] Class 클래스 [get,set 구문 오류 필독] (0) | 2021.02.04 |
[Javascript] 이벤트 전파 방지 stopPropagation() (0) | 2021.02.03 |
[Javascript] 이벤트의 추가 addEventListener() (0) | 2021.02.02 |
댓글