자바스크립트 JS 비동기 처리와 콜백지옥을 알아보자 (+setTimeout)
1. 먼저 비동기 처리를 알아보자!
자바스크립트 코드 실행은 두 가지 방식으로 나눠 볼 수 있습니다.
하나, 동기적인 처리
a=1; b=2; c=3;
console.log(a);
console.log(b);
console.log(c);
코드의 상단부터 각각의 로직a,b,c가 있습니다. 이때 동기적인 처리가 이뤄진다면 실행 순서는 A>B>C 순입니다.
둘, 비동기 처리
a = 1;
b = 2;
c = 3;
setTimeout(() => console.log(a), 500);
console.log(b);
console.log(c);
다시 로직 a,b,c가 있습니다. 앞선 예시와 다른 점은 a가 setTimeout 을 통해 0.5초 뒤에 실행된다는 점입니다.
이때 b와 c가 a보다 먼저 출력될까요? 아니면 순서대로 출력될까요???
결과는 b>c>a 순입니다.
이렇게 특정 로직의 실행이 끝날 때까지 기다려주지 않고,
나머지 코드를 먼저 실행하는 것이 비동기 처리입니다.
setTimeout은 대표적인 비동기 처리의 사례가 되겠습니다.
2. 비동기 처리의 문제점& 콜백함수를 사용한 해결
코드를 실행했을때 0.5초 뒤에 a가 출력되고 그다음 b,c가 순차적으로 출력되기를 원하는 상황에서
비동기 처리는 내가 원하지 않았던 b,c,a의 순서로 값을 출력합니다.
즉 순서를 보장 받을수 없게 됩니다.
이때 콜백함수를 사용하면 이러한 문제를 해결 할 수 있습니다.
a = 1;
b = 2;
c = 3;
setTimeout(() => {
console.log(a);
setTimeout(() => {
console.log(b);
setTimeout(() => {
console.log(c);
}, 500);
}, 500);
}, 1000);
a는 1초뒤, b와 c는 0.5초 뒤 실행되게 설정해놨습니다. b>c>a순으로 실행될 것 같지만,
콜백함수로 비동기 처리의 문제점을 개선했기에
a,b,c는 순차적으로 실행됩니다.
3. 콜백함수 지옥 사례
저는 a,b,c 외에 d,e,f~~~~~z까지,
각각의 시간간격을 두고,
콘솔로 출력하고 싶어졌습니다.
계속된 동기적인 처리를 요구하는 상황에서 콜백함수가 콜백함수의 꼬리의 꼬리를 물고 무한정 길어지기 시작합니다.
setTimeout(() => {
console.log(a);
setTimeout(() => {
console.log(b);
setTimeout(() => {
console.log(c);
setTimeout(() => {
console.log(d);
setTimeout(() => {
console.log(e);
setTimeout(() => {
console.log(f);
}, 50);
}, 522);
}, 1600);
}, 500);
}, 500);
}, 1000);
이떄 q의 출력 시간 설정을 수정하고 싶어졌습니다.
가독성이 심하게 떨어져서 수정이 어렵지 않나요??
저는 예시를 console.log와 setTime으로 들었습니다만, 더 복잡한 로직은 어떻게 되는걸까요?
4. 콜백지옥의 해결방안
중첩된 함수들을 분리하여, 각각의 함수로 자리하게 한다면, 해결될 수 있습니다.
그러나 해당 방법이 최고의 방법이라고 보긴 어렵습니다.
왜냐면 Promise 혹은 Async를 사용하여 그 문제를 더 효과적으로 해결할 수 있기 때문입니다.
다음 글에서 Promise와 Async에 대하여 알아보겠습니다.