콜백 함수를 통해 비동기 방식에서도 순차적으로 로직을 실행할 수 있다.
앞서 실행된 명령이 끝난 다음 순차적으로 다음 코드를 실행하는 것이다.
앞서 실행된 명령이 끝날 때까지 기다리지 않고 다음 코드를 먼저 실행하는 것이다.
console.log(1);
console.log(2);
setTimeout(function () {
console.log(3);
}, 5000);
console.log(4);
// 1 2 4 3
setTimeout
함수가 종료되는 것을 기다리지 않고, 바로 다음 코드인 console.log(4);
를 실행한다.
다음에 실행할 로직를 콜백 함수로 전달하여 로직이 끝났을 때 호출할 수 있다.
time초 후에 실행되는 함수 timer가 있다.
function timer (time, callback) {
setTimeout(function () {
callback();
}, time);
}
timer(1000, function () {
console.log('작업');
timer(1000, function () {
console.log('작업');
});
});
// (1초) 작업 (1초) 작업
이어지는 timer 함수를 콜백 함수로 전달하여 순차적으로 동작을 실행한다.
만약 timer 함수를 100번 실행해야 한다면?
timer(1000, function () {
console.log('작업');
timer(1000, function () {
console.log('작업');
timer(1000, function () {
console.log('작업');
timer(1000, function () {
console.log('작업');
timer(1000, function () {
console.log('작업');
// ...
});
});
});
});
});
콜백 안에 콜백을 계속 무는 형식으로 코드가 작성되어 들여 쓰기가 심각하게 깊어지는 콜백 지옥이 발생한다.
기명 함수를 사용하면 콜백 지옥을 해결할 수 있다.
timer(1000, timer1);
function timer1 () {
console.log('작업');
timer(1000, timer2);
}
function timer2 () {
console.log('작업');
timer(1000, timer3);
}
function timer3 () {
console.log('작업');
timer(1000, timer4);
}
// ...
ES6부터는 Promise, ES8부터는 async function으로 더욱 쉽게 해결할 수 있다.