어떤 작업을 요청했을 때 그 작업이 종료될때 까지 기다린 후 다음 작업을 수행하는 방식이다.
어떤 작업을 요청했을 때 그 작업이 종료될때 까지 기다리지 않고 다른 작업을 하고 있다가, 요청했던 작업이 종료되면 그에 대한 추가 작업을 수행하는 방식이다. 언제 코드가 실행될지 예측할 수 없다.
자바스크립는 호이스팅이된 코드 이후부터 한줄한줄 제일 위에서부터 밑으로 동기적으로 실행된다.
밑에 작성된 코드를 끌어올려 우선적으로 실행해주는 것을 말한다. var 변수나 함수 선언이 호이스팅 되게 된다. 즉 밑에서 선언된 var나 function이 제일 위로 끌어올려져 실행된다.
console.log('1')
console.log('2')
console.log('3')
위의 코드는 위에서 부터 하나하나씩 실행되어 1 -> 2 -> 3 순서로 출력된다. 동기적으로 실행된 것이다.
인자로 함수를 받는 함수이다. 브라우저가 함수를 가지고 있다가 때가 됐을때 실행시킨다.
setTimeout(function () { //setTimeout의 인자로 function함수가 전달되었다.
console.log('2')
}, 1000)
위와 같은 형태로 함수의 인자로 함수가 전달되는 형태이다. 콜백함수는 동기적 콜백함수와 비동기적 콜백함수로 나뉘어 진다.
function printImmediately(print) {
print()
}
printImmediately(() => console.log('hello'))
위 코드에서 printImmediately 함수는 콜백함수 형태지만 따로 시간지연 없이 즉각적으로 실행되는 동기적 콜백함수이다.
console.log('1')
setTimeout(function () {
console.log('2')
}, 1000)
console.log('3')
위 코드는 setTimeout으로 2를 출력하는 부분이 비동기 처리되어 먼저 1 -> 3 순서로 먼저 출력이 되고, 1000ms가 지난 후에 브라우저로부터 요청받아 2를 마지막으로 출력해준다. 이런 형태가 비동기적 콜백함수이다. 자바스크립트에서는 이런 비동기적 콜백함수를 이용하여 비동기적인 실행을 해준다.
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);
}
getRoles(user, onSuccess, onError) {
setTimeout(() => {
if (user === 'ellie') {
onSuccess({ name: 'ellie', role: 'admin' });
} else {
onError(new Error('no access'));
}
}, 1000);
}
}
const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your passrod');
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);
}
);
자바스크립트로 콜백함수를 이용해서 사용자 정보를 입력받아 그 정보를 띄어주는 코드이다. 함수에서 성공적으로 처리될 때와 에러가 났을 때 각각 함수를 전달받고 성공적으로 전달 받았을 때 또 전달받은 함수 안에서 콜백함수를 전달받고 그 안에서 또 성공했을 때와 실패했을 때를 나뉘어 함수를 전달받아 실행한다. 이런 방식이라면 코드를 쓰고 해석하는 것이 아주 불편해질 것이다. 이렇게 콜백함수 안에 콜백함수가 연쇄적으로 구현되어 코드가 난잡해지는 것을 '콜백지옥'이라고 한다.
콜백지옥의 예시처럼 콜백함수를 함수 안에 중첩해서 사용하면 가독성이 너무 떨어진다. 어디서 어떻게 연결돼 있는지 한눈에 알아보기 어렵다. 이런 콜백지옥이 펼쳐지면 나중에 디버깅할 때와 유지보수를 할 때 매우 어려워진다.