프로그래밍 언어/Javascript

비동기 처리의 시작 콜백 이해하기, 콜백 지옥 예제

김곰댕 2021. 8. 24. 16:36
728x90
<!DOCTYPE html>
<html lang = "en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" consent="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script src="async/callback.js"></script>
    </head>
    <body></body>
</html>

1. 동기와 비동기

// 자바스크립트는 동기적임 - 호스팅이 된 이후부터 코드가 작성된 순서에 맞춰 하나하나 동기적으로 실행

// hoisting : var, function 선언 등이 자동적으로 제일 위로 올라가는것

 

1) 동기 : 정해진 순서에 맞게 코드가 실행되는 것 

console.log('1');
console.log('2');
console.log('3');

출력 결과

2) 비동기 : 언제 코드가 실행될지 예측할 수 없는 것

console.log('1'); //동기
setTimeout(() => console.log('2'), 1000); //지정한 시간이 지나면 지정한 callback함수를 호출 / setTimeout(,시간); 시간은 1000밀리세컨드(1초) / 비동기
//callback함수 : 전달해준 함수를 나중에 호출
console.log('3'); //동기

출력 결과

2. callback

1) 동기적인 callback

//1) 동기적인 callback
function printImmediately(print) //함수선언 호스팅
{
    print();
}
printImmediately(()=> console.log('hello')); //동기

출력 결과

2) 비동기적인 callback

//2) 비동기적인 callback
function printWithDelay(print, timeout) //함수선언 호스팅
{
    setTimeout(print, timeout);
}
printWithDelay(() => console.log('async callback'), 2000); //2초뒤에 호출 / 비동기

출력 결과

3. 콜백 지옥 예제

문제점 : 

1) 가독성이 떨어짐

2) 에러발생 혹은 디버깅시에 어려움

3) 유지보수가 어려움

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')); //콜백 호출 / Error오브젝트 생성
            }
        }, 2000); //2초후에
    }
    getRoles(user, onSuccess, onError)
    {
        setTimeout(() => {
            if(user === 'ellie')
            {
                onSuccess({name: 'ellie', role: 'admin'}); //콜백 호출 / 오브젝트 전달
            }
            else
            {
                onError(new Error('no access')); //콜백 호출 / 오브젝트 생성
            }
        }, 1000); //1초후에
    }
}

// 1) 사용자에게 id와 password를 입력받음

// 2) 서버에 로그인

// 3) 로그인에 성공한 아이디를 받아서 다시 역할을 요청해 받아옴

// 4) 사용자 오브젝트를 출력

const userStorage = new UserStorage();
const id = prompt('enter your id'); //prompt(입력창에서 띄워줄 메시지, 입력 부분의 기본값) - 문자열을 입력할 때  사용
const password = prompt('enter your password');
userStorage.loginUser(
    id, 
    password, 
    (user) =>
    {
        userStorage.getRoles(
            user, 
            (userWithRole) =>
            {
                //alert : 웹상에 띄워지는 작은박스창(alert창)을 띄움
                alert(`Hello ${userWithRole.name}, you have a ${userWithRole.role} role`);
            },
            (error) =>
            {
                console.log(error);
            } 
        )
    },
    (error) =>
    {
        console.log(error);
    }
);

id 입력
password
출력 결과

 

728x90