할머니의 콤퓨타 도전기

(JavaScript) Callback 본문

Web Front-end/Javascript

(JavaScript) Callback

ji.o.n.e 2021. 5. 5. 02:45

JavaScript is synchronous!

  • Execute the code block in order after hoisting.
  • hoisting이 된 이후부터 code가 작성한 순서에 맞춰서 하나씩 동기적으로 실행
  • 정해진 순서에 맞게 코드가 실행되는 것
  • hoisting
    • var, function declaration 선언들이 자동적으로 제일 위로 올라감
console.log('1');
console.log('2');
console.log('3');
// 1
// 2
// 3

javascript engine은 코드를 제일 위에서부터 밑으로 실행한다. 따라서 가장 먼저 console.log('1');를 만나고 1 출력하고 그 다음 setTimeout은 browser API 이므로 브라우저에게 1초 뒤에 전달해준 콜백함수를 실행해달라고 요청한다. browser API는 무조건 브라우저한테 먼저 요청을 보낸다. 이후 응답을 기다리지 않고 바로 console.log('3');로 넘어가서 3 출력한다. 마지막으로 브라우저에서 1초의 시간이 지난 후에 콜백 함수 실행하라고 요청하면 그때 console.log('2'); 실행된다.

 

Synchronous callback

function printImmediately(print) {
    print();
}
printImmediately(() => console.log('hello'));
// 1
// 3
// hello
// 2

 

Asynchronous callback

function printWithDelay(print, timeout) { // 모든 함수의 선언은 hoisting되기 때문에 선언이 제일 위로 올라감
    setTimeout(print, timeout);
}
printWithDelay(() => console.log('async callback'), 2000);
// 1 (동기)
// 3 (비동기)
// hello (동기)
// 2 (동기)
// async callback (비동기)

 

Callback Hell example

class UserStorage {
    loginUser(id, password, onSuccess, onError) {
        setTimeout(() => {
            if ((id === 'jiwon' && password === '1234') ||
                (id === 'coder' && password === '0000')
            ) {
                onSuccess(id);
            } else {
                onError(new Error('not found'));
            }
        }, 2000);
    }

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

위 UserStorage class를 이용해서 아래와 같이 구현하고자 한다.

  1. 사용자에게 id, password 입력받아옴
  2. 받아온 id, password로 login
  3. login이 성공적이라면 login한 사용자의 id를 다시 받아옴. 받아온 id를 이용해 역할 요청
  4. 역할이 성공적으로 받아와진다면, 사용자의 object를 받아옴. 이를 출력
const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your password');
userStorage.loginUser(id, password, (user) => {
    userStorage.getRoles(user, (userWithRole) => {
        alert(`Hello ${userWithRole.name}, you have a ${userWithRole.role} role`);
    }, (error) => { console.log(error) })
}, (error) => {
    console.log(error);
})

이처럼 콜백함수 안에서 다른 것을 호출하고 또 다른 콜백을 전달하고... 또 다른 호출하고 전달하고... 를 반복하도록 구현하면 콜백 지옥이 된다.

 

문제점

  • 가독성이 떨어짐
  • 디버깅이 어려워짐
  • 유지보수가 어려움



 

 

 

'Web Front-end > Javascript' 카테고리의 다른 글

(JavaScript) async & await  (0) 2021.05.05
(JavaScript) Promise  (0) 2021.05.05
(JavaScript) JSON  (0) 2021.05.05
(Javascript) Array APIs  (0) 2021.05.04
(Javascript) Object  (0) 2021.05.04
Comments