JavaScript & Node.js

#.12 비동기 [Callback]

Haksae 2022. 1. 9. 15:40

1. Synchronous(동기) vs Asynchronous(비동기)

  • 자바스크립트는 동기적인 언어이다.
    • 호이스팅이 된 이후부터 코드가 작성한 순서에 맞춰서 하나씩 동기적으로 실행된다.
    • hoisting (호이스팅) : var 변수와 함수선언(function declaration)들이 자동적으로 제일 위로 올라가는 것
  • 비동기 : 비동기적으로 언제 코드가 실행될지 예측할 수 없는 것을 뜻함
console.log('1'); // 동기적으로 처리
setTimeout(()=> console.log('2'), 1000); // 비동기적으로 처리 
console.log('3');

2. callback function

  • 자바스크립트는 함수를 콜백형태로 파라미터로 다른 함수에 전달할 수도 있고, 변수에 할당할 수도 있는 언어임
  • 콜백 함수
    • 함수 안에 하나의 파라미터로 전달됨
    • 함수를 보낼테니 다시 콜해줘. 콜백해달라고 전달하는 함수를 콜백 함수
  • Synchronous callback (동기 콜백)
    • 선언은 호이스팅되어 먼저 되지만, 실행은 동기적으로 된다.
console.log('1'); // 동기적으로 처리
setTimeout(()=> console.log('2'), 1000); // 비동기적으로 처리 
console.log('3');

function printImmediately(print) {
    print();
};

printImmediately(()=> console.log('hello'));
// 출력 1 3 hello 2
  • Asynchronous callback (비동기 콜백)
    • 선언은 호이스팅되지만, 콜백 함수는 비동기적으로 처리된다.
  • 예시 1 (비동기 콜백)
    • setTimeout() : 브라우저에서 제공하는 API, 지정한 시간이 지나면 콜백 함수 호출
console.log('1'); // 동기적으로 처리

function printWithDelay (print, timeout) {
    setTimeout(print, timeout);
}
printWithDelay(()=> console.log('asyn callback'), 2000)

console.log('2');
  • 예시2 (비동기 콜백)
//form
setTimeout(function() {
	console.log('2');
}, 1000);

// arrow function
setTimeout(()=> console.log('2'), 1000); 

3. 콜백 지옥

  • 콜백 함수 안에서 계속해서 콜백 함수를 부르는 경우... 지옥이 펼쳐진다.
// Callback Hell example
class UserStorage{
    loginUser(id, password, onSuccess, onError){
        setTimeout(()=>{
            if(
                (id === 'hak' && password == 'sae') ||
                (id === 'coder' && password == 'academy')
            ){
                onSuccess(id);
            }else{
                onError(new Error('not found'));
            }
        }, 2000);
    }

    getRoles(user, onSuccess, onError){
        setTimeout(()=> {
            if(user === 'hak'){
                onSuccess({name: 'hak', role: 'admin'});
            }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,
    password,
    (user)=>{
        userStorage.getRoles(user, (userWithRole)=>{
            alert(`Hello ${userWithRole.name}, you have a ${userWithRole.role} role`);
        },(error)=>{console.log(error);})
    },
    (error) =>{console.log(error);}
);
  • 콜백 지옥 단점
    • 가독성이 좋지 않음
    • 에러 발생, 디버깅하기에 어려움
    • 유지보수도 어려움
    → 해결 방법 promise, async

출처 : 드림코딩엘리 https://www.youtube.com/channel/UC_4u-bXaba7yrRz_6x6kb_w