자바스크립트 함수질문

조회수 464회
//Callback Hell example
class UserStorage {
    loginUser(id, password, onSuccess, onError){
        setTimeout(()=>{
            if(
                (id==='ellie'&&password==='dream') ||
                (id==='coder'&&password==='academy') 
            ) {
                onSuccess(id);
            } else {
                onError(new Error('not found'));
            }
        }, 2000); // 로그인하는데 2초 걸린다 가정
    }

    getRoles(user, onSuccess, onError){
        setTimeout(()=>{
            if(user === 'ellie') {
                onSuccess({name:'ellie', role:'admin'}); // 성공시 name과 role 키&벨류를 전달
            } else {
                onError(new Error('no access'));
            }
        }, 1000);
    }
}

const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your password'); //사용자에게 데이터를 받아옴
userStorage.loginUser(
    id, // 받아온 id
    password,  // 받아온 password 전달
    user => { // 성공시 사용자의 데이터를 받아옴 id == user
        userStorage.getRoles( // 그리고 사용자의 역할을 받아옴
            user, // id 전달
            userWithRole => { 
                alert(`Hello ${userWithRole.name}, you have a ${userWithRole.role} role`)
            },
            error => {
                console.log(error)
            }
        );
    },
    error => { // 로그인 실패시 에러발생
        console.log(error);
    }
);

여기서 loginUser()와 getRoles() 함수의 onSuccess 파라미터를 보면 onSuccess(파라미터); 이렇게 되어 있는데 이게 성공할시 파라미터를 전달한다는 거 같은데 밑에 코드에서 실행할때 보면 getRoles같은 경우는 두번째 파라미터 즉, userWithRole에 그 전달된 파라미터 자체를 가지고 있다는 건가요? 넘 헷갈리네요

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • getRoles() 메소드는 user === 'ellie'일 때 onSuccess 인자 자리에 들어가 있는 함수(이하 "성공콜백")를 실행하겠다는 계획을 갖고 있습니다.
    그 성공콜백에게는 객체를 하나 넘겨주겠다는 것까지 포함해서요.

    그리고 성공콜백은 어쨌든 함수겠지요?
    그렇다면 그 함수를 정의해 봅시다. 넘겨받은 객체를 가지고 alert()만 딱 실행하는 거죠.

    // 객체를 하나 받으면 alert 를 실행한다.
    function (objFromGetRoles) {
        alert(`Hello ${objFromGetRoles.name}, you have a ${objFromGetRoles.role} role`);
    }
    

    이걸 활용하자면 이렇게 붙여넣게 되겠지요. 이렇게 하면, getRoles() 메소드가 성공시 저 콜백을 실행하면서 objFromGetRoles 자리에 객체 한 개를 넘겨줄 테니, 잘 동작할 테고요.

    userStorage.getRoles(
        user,
        // 이 메소드가 실행되는 시점에서 이미 getRoles 가 객체 하나를 정해서 objFromGetRoles 에 넣어줄 것이다
        function (objFromGetRoles) {
            alert(`Hello ${objFromGetRoles.name}, you have a ${objFromGetRoles.role} role`);
        },
        // 이하생략
    );
    

    음 근데 너무 못생겼군요! 화살표 함수를 도입해볼 수 있을 겁니다.

    userStorage.getRoles(
        // 전략
        objFromGetRoles => {
            alert(`Hello ${objFromGetRoles.name}, you have a ${objFromGetRoles.role} role`);
        },
        // 후략
    );
    

    그리고 다시 보니 변수명도 좀 별로군요! 바꿔봅시다.

    userStorage.getRoles(
        // 전략
        userWithRole => {
            alert(`Hello ${userWithRole.name}, you have a ${userWithRole.role} role`);
        },
        // 후략
    );
    

    앗! 이게 최종 코드군요.

    핵심은 크게 두 가지입니다. userWithRole이라는 이름 자체는 익명함수의 파라미터명이기 때문에 크게 중요하지 않다는 것, 그리고 그 자리에 뭐가 들어가느냐는 순전히 그 콜백이 실행되는 맥락에 의존한다는 것이죠.

    저도 이 이상 엄밀한 이론적 설명은 드리기 어렵습니다만 말하자면 그렇다는 얘기입니다. 설명이 됐기를 바랍니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)