자바스크립트는 싱글스레드
언어라는 단점이 있어 엔진 구조상으로 한번에 하나의 함수만 동기적으로 실행이 가능합니다. 하지만 이렇게 되면 앞의 작업 시간이 길어질수록 시간 및 자원의 낭비가 심해지게 됩니다.
이러한 문제점을 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 비동기 호출로 극복을 할 수 있습니다.
대표적으로 Web API를 사용 하면 코드는 비동기로 동작을 할 수 있습니다. setTimeout()
을 예시로 들어보도록 하겠습니다.
console.log('1');
setTimeout(() => {
console.log('2');
},1000);
console.log('3');
아직 비동기 처리에 대한 이해가 없는 상태라면 1 -> 2 -> 3 순서로 출력이 될 것이라고 생각할 수 있습니다.
하지만 실제로 코드를 실행해보면 1 -> 3 -> 2 순서로 출력이 되는 것을 확인할 수 있습니다.
이는 setTimeout()
이 비동기적으로 실행되기 때문에 1초를 기다렸다가 다음 코드를 수행하는 것이 아니라 setTimeout()
을 실행하고 나서 바로 다음 코드를 실행하기 때문입니다. 따라서 1 -> 3 출력 후 1초 후 2 가 출력되게 되는 것입니다.
그렇다면 이러한 문제점을 어떻게 해결을 할 수 있을까요? 대표적인 문제점 해결방법에는 아래 3가지가 있습니다. 이제부터 이 3가지 방법에 대해 공부를 해보도록 하겠습니다.
callback()
사용Promise
async/await
앞서 작성했던 코드의 문제점을 콜백함수를 통해 보완해보도록 하겠습니다.
console.log('1');
function setTimeoutWithCallback(callbackFunc) {
setTimeout(() => {
console.log('2');
callbackFunc()
},1000);
}
setTimeoutWithCallback(() => console.log('3'))
코드 실행 결과 1 출력 후 2초 후 2와 3이 출력되는 것을 확인할 수 있습니다. 이렇게콜백함수를 이용하면 특정로직이 끝났을 때 원하는 동작을 실행시킬 수 있습니다.
콜백 함수를 이용하면 비동기처리 방식의 문제점을 해결 할 수 있지만, 연속해 사용을 함으로써 문제가 발생할 수 있습니다.
setTimeout(function() {
console.log('A');
setTimeout(function() {
console.log('B')
setTimeout(function() {
...
console.log('C')
}, 1000)
},1000)
}, 1000)
이를 콜백지옥이라고 하며 이렇게 콜백함수를 남용하게 되는 경우 가독성은 떨어지고 로직을 변경하기도 어렵게 됩니다. 이를 Promise
와 async/await
를 이용해 해결할 수 있습니다.
다음 포스팅에 promise
와 async/await
에 대해서도 알아보도록 하겠습니다.