자바스크립트는 synchronous하다.

호이스팅이 된 후에 순서대로 코드가 실행된다.

호이스팅: var, function declaration이 자동적으로 제일 위로 올라가는 것.

동기적

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

결과
1
2
3

asynchronous라 함은 코드가 적혀 있는 순서대로 실행되지 않는 것을 말한다.

console.log('1');
setTimeout(function () {
    console.log('2');
}, 1000);
console.log('3');

setTimeout은 브라우저 API이므로 콜스택에 쌓이지 않고 API 백그라운드에 들어가게 된다. 그 후에 동기적인 작업인 console.log(’3’)을 실행한 뒤에 스택이 비어 있으면 이벤트 루프에 의해 콜백 함수가 실행된다.

synchronous callback & asynchronous callback

콜백 함수도 동기적, 비동기적으로 둘 다 구현할 수 있다.

그 안에 비동기적인 작업을 넣느냐 마느냐

console.log('1');
setTimeout(function () {
    console.log('2');
}, 1000);
console.log('3');

// synchronous callback
function printImmediately(print) {
    print();
}
printImmediately(()=>console.log("hello"));

// asynchronous callback
function printWithDelay(print, timeout) {
    setTimeout(print, timeout);
}
printWithDelay(()=>console.log("async hello"), 2000);

결과
1
3
hello
2
async hello

Callback Hell 구현해보기

API 클래스

class UserStorage {  // 서버에서 사용자의 데이터를 가져오는 class
    loginUser(id, password, onSuccess, onError){  // 1. 먼저 사용자의 아이디와 패스워드를 받아온다.
        setTimeout(() => {
            if (
                (id === 'ellie' && password === 'dream') ||
                (id === 'coder' && password === 'academy')
            ) {
                onSuccess(id);  // 2. 사용자의 아이디를 받아온 다음
            } else {
                onError(new Error('not found'));
            }
        }, 1000);
    }

    getRoles(user, onSuccess, onError) {
        setTimeout(()=> {
            if (user === 'ellie') {   // 3. 그 아이디가 ellie라면 
                onSuccess({name : 'ellie', role: 'admin'});  
                // 4. role을 admin으로 만들어서 보내준다.
                // 5. 그 name과 role을 출력해준다.
            } else {
                onError(new Error('no access'));
            }
        }, 1000);
    }
}