자바스크립트 Promise로 더러운 코드 수정하기

hkkm·2021년 4월 2일
0

이 글은
유튜브 드림 코딩 채널의
자바스크립트 12. 프로미스 개념부터 활용까지 JavaScript Promise | 프론트엔드 개발자 입문편 (JavaScript ES6)
를 영상을 보면서 작성하는 글이다.

콜백 함수가 많은 코드를 Promise를 활용하여 정리할 것이다.

아래 예시는 user의 id와 password를 받아서 admin인지 아닌지 확인하는 코드이다. (가독성이 좋지 않다.)

1. 더러운 코드

class UserStorage {
    loginUser(id, password, onSuccess, onError){
        setTimeout(() => {
            if(
                (id === 'HM' && password === 'KM123') ||
                (id === 'KM' && password === 'KM321')
            ) {
                onSuccess(id);
            }
            else {
                onError(new Error('id & pwd not found'));
            } 

        }, 1000);
    }

    getRoles(user, onSucces, onError){
        setTimeout(() =>{
            if(user == 'HM'){
                onSucces({name:'HM', role:'admin'});
            } 
            else {
                onError(new Error('no access'));
            }
        } , 1000);
    }
}


//1. id와 pwd를 받는다.
//2. 로그인한다.
//3. 역할을 가져온다.
//4. 역할을 확인한다.
const user_storage = new UserStorage();
const id = prompt('Your ID? ');
const pwd = prompt('Your pwd? ');

user_storage.loginUser(id, pwd, 
    (user) => {
        user_storage.getRoles(
        user, 
        (user_role) => {
            alert(`welcome! ${user_role.name}~ you are ${user_role.role}`);
        }, 
        (error) => {
            console.log(error);
            console.log('you are not admin');
        });
    },
    (error) => console.log(error)
    
); 

2. 콜백함수를 Promise 객체로 대체하기

먼저 UserStorage class의 함수들을 고쳐준다.
loginUser의 callback함수 parameter를 없애고 대신 Promise 객체를 return 하는 형태로 만든다.

getRoles도 마찬가지로 callback parameter를 없애고 Promise 객체를 활용한다.

각각 onSuccess, onError를 Promise의 resolve와 reject로 대체했다.

class UserStorage {
    loginUser(id, password){
        return new Promise((resolve, reject)=>{
            setTimeout(() => {
                if(
                    (id === 'HM' && password === 'HM123') ||
                    (id === 'PM' && password === 'PM321')
                ) {
                    resolve(id);
                }
                else {
                    reject(new Error('id & pwd not found'));
                } 
    
            }, 1000);
        });
        
    }

    getRoles(user){
        return new Promise((resolve, reject) => {
            setTimeout(() =>{
                if(user == 'HM'){
                    resolve({name:'HM', role:'admin'});
                } 
                else {
                    reject(new Error('no access'));
                }
            } , 1000);
        });
        
    }
}

3. then, catch 사용

user의 입력값이 전달된 후의 동작을 theh과 catch method를 이용하여 처리한다.

const user_storage = new UserStorage();
const id = prompt('Your ID? ');
const pwd = prompt('Your pwd? ');


user_storage.loginUser(id, pwd)
    .then((user)=>user_storage.getRoles(user))
    .then((user_role)=>{
        alert(`welcome! ${user_role.name}~ you are ${user_role.role}`);
    })
    .catch((error)=>console.log(error));

loginUser()와 getRoles() method 모두 Promise 객체를 반환하므로 chaining이 가능하다.

4. 실행결과

위의 2, 3번의 코드를 합쳐서 실행해보면
아래와 같이 뜬다.

ID에 HM,

pwd에 HM123를 입력하면
아래와 같은 창이 뜬다.

다른 경우에는 브라우저 console 창에 에러 문구가 뜬다.

0개의 댓글