HTML과 CSS로 웹페이지의 겉모습을 멋지게 꾸미고 나면, 사용자의 행동에 반응하여 동적으로 움직이게 만드는 자바스크립트(JavaScript)의 세계로 깊숙이 들어가게 된다. 자바스크립트를 공부하다가 초보자들이 가장 거대하고 높은 논리적 장벽을 마주하는 순간이 있다. 바로 '비동기 처리'와 악명 높은 '콜백 지옥(Callback Hell)'이다.
화면이 멈춘 것처럼 보이거나, 데이터가 아직 도착하지도 않았는데 화면에 먼저 뿌리려고 하다가 에러가 터지는 상황을 겪으면 개발을 포기하고 싶어질 만큼 머릿속이 복잡해진다.
[소제목] 동기(Synchronous)와 비동기(Asynchronous)의 차이점
자바스크립트는 기본적으로 위에서 아래로 한 줄씩 코드를 차례대로 실행하는 싱글 스레드(Single Thread) 언어다. 즉, 한 번에 한 가지 일밖에 처리하지 못한다.
동기적 처리: 첫 번째 작업이 완전히 끝날 때까지 다음 작업은 줄을 서서 무조건 기다려야 하는 구조다. 만약 서버에서 엄청나게 큰 데이터를 가져오느라 3초가 걸린다면, 그동안 웹페이지 전체가 멈춰버리는 끔찍한 사용자 경험을 낳게 된다.
비동기적 처리: 시간이 오래 걸리는 작업(예: 서버에 데이터 요청하기, 파일 읽어오기 등)을 요청해 두고, 그 작업이 끝날 때까지 기다리지 않고 곧바로 다음 코드를 먼저 실행하는 방식이다. 작업이 끝나면 '완료되면 이 함수(콜백)를 실행해줘'라고 부탁해 둔다.
이 비동기 덕분에 웹페이지가 멈추지 않고 부드럽게 작동할 수 있지만, 반대로 코드가 실행되는 순서가 뒤죽박죽이 되기 때문에 초보자들의 멘탈을 흔들어 놓는다.
[소제목] 콜백 지옥이란 무엇이며 왜 발생하는가
서버에서 데이터를 받아온 뒤, 그 데이터를 가지고 다시 두 번째 작업을 하고, 또 그 결과를 이용해 세 번째 작업을 해야 하는 상황을 가정해 보자. 비동기 작업의 특성상 순서를 보장받으려면 함수 안에 또 다른 함수를 매개변수(콜백)로 계속해서 집어넣어야 한다.
직접 코드를 짜다 보면 코드가 오른쪽으로 점점 밀려나면서 꺾쇠 모양(}}}})이 산더미처럼 쌓이는 기괴한 형태를 마주하게 된다.
가독성이 바닥을 치며, 어디서부터 어디까지가 어떤 로직인지 코드를 눈으로 쫓는 것조차 불가능해진다.
에러 처리를 하려고 해도 들여다보기 힘든 구조 때문에 디버깅 지옥에 빠지게 된다.
이 문제를 해결하기 위해 자바스크립트 진영은 눈부신 진화를 거듭해 왔으며, 현재는 콜백 지옥을 우아하게 탈출할 수 있는 강력한 무기들을 기본으로 제공하고 있다.
[소제목] 프로미스(Promise)와 async/await으로 비동기 정복하기
현대 자바스크립트 개발에서는 콜백 지옥의 고통을 끝내기 위해 프로미스(Promise) 객체와 async/await 문법을 적극적으로 사용한다. 직접 겪어본 바에 따르면 이 문법을 이해하고 난 뒤부터 비동기 코드가 거짓말처럼 읽기 쉬워진다.
프로미스(Promise): 비동기 작업의 '성공(Resolved)' 또는 '실패(Rejected)' 상태를 약속 형태로 관리해 주는 객체다.
.then()체이닝을 이용해 코드가 아래로 깔끔하게 흐르도록 정리할 수 있다.async/await: 프로미스보다 한 단계 더 나아가, 비동기 코드를 마치 동기 코드처럼 자연스럽게 작성할 수 있게 해주는 혁신적인 문법이다. 함수 앞에
async를 붙이고, 기다려야 하는 비동기 작업 앞에await를 붙여주면 서버 응답이 올 때까지 기다렸다가 다음 줄이 실행된다.
예를 들어 서버 데이터를 가져올 때 아래와 같이 직관적으로 코드를 짤 수 있다.
async function fetchData() {
try {
const response = await fetch('
이처럼 try...catch 구문을 활용해 에러까지 안전하게 잡아낼 수 있으므로, 비동기 처리를 다룰 때는 가급적 async/await 패턴을 몸에 익히는 것이 현명하다.
[소제목] 초보자가 자주 하는 실수와 주의사항
비동기 코드를 다룰 때 가장 흔하게 저지르는 실수는 await 키워드를 빼먹은 채 비동기 함수의 결과값을 변수에 담으려고 하는 것이다. await 없이 데이터를 받으면 값이 아니라 아직 완료되지 않은 'Promise 객체' 자체를 받아버리기 때문에 이후의 모든 연산이 undefined 에러를 뿜어낸다.
또한, 비동기 함수 내부에서 에러가 발생했을 때 try...catch로 감싸주지 않으면 에러가 조용히 묻히거나 콘솔에 빨간 불이 들어와도 원인을 찾기 어렵다. 처음에는 비동기의 흐름이 눈에 보이지 않아 혼란스럽겠지만, 콘솔에 단계별로 로그를 찍어가며 순서를 추적하는 연습을 반복하면 감을 잡을 수 있다.
핵심 요약:
자바스크립트는 싱글 스레드 언어이므로 웹페이지 멈춤 현상을 막기 위해 비동기 처리가 필수적이다.
콜백이 중첩되어 가독성이 무너지는 '콜백 지옥' 현상은 코드를 복잡하게 만드는 주범이다.
최신 표준인
async/await문법과try...catch를 활용하면 비동기 코드를 동기 코드처럼 직관적이고 안전하게 작성할 수 있다.
다음 편 예고: 다음 편에서는 API 호출 시 초보자들이 가장 자주 겪는 CORS(교차 출처 리소스 공유) 에러의 원인과 이해를 다룬다.
이 글을 읽으면서 자바스크립트 비동기 처리나 콜백 때문에 머리가 아팠던 기억이 있다면 댓글로 편하게 공유해 주세요!
0 댓글