동기와 비동기 개념을 이해하고 나면 자연스럽게 한 가지 의문이 남는다. “그럼 비동기는 도대체 어떻게 동시에 처리되는 것처럼 보일까?” 나도 처음에는 이게 가장 헷갈렸다. 코드상으로는 하나씩 실행되는 것 같은데, 실제로는 여러 작업이 동시에 돌아가는 것처럼 느껴졌기 때문이다. 이걸 가능하게 해주는 핵심 구조가 바로 이벤트 루프(Event Loop)다.

이벤트 루프는 작업을 ‘순서대로’ 처리하면서도 동시에 실행되는 것처럼 보이게 만든다
많은 사람들이 이벤트 루프를 들으면 멀티스레딩처럼 여러 작업을 동시에 처리하는 구조라고 생각하기 쉽다. 하지만 실제로는 하나의 스레드에서 동작하는 경우가 많다. 핵심은 “동시에 처리하는 것”이 아니라 “빠르게 번갈아 처리하는 것”이다.
이벤트 루프는 계속 반복하면서 실행할 작업이 있는지 확인한다. 작업이 있으면 하나를 꺼내서 실행하고, 끝나면 다시 다음 작업을 확인하는 식이다. 이 과정이 매우 빠르게 반복되기 때문에, 사용자 입장에서는 여러 작업이 동시에 처리되는 것처럼 느껴진다.
나도 이 개념을 처음 접했을 때는 “이게 진짜 동시에 처리되는 게 아니라고?”라는 생각이 들었다. 그런데 구조를 이해하고 나니까, 왜 비동기 코드가 그렇게 자연스럽게 동작하는지 조금씩 보이기 시작했다.
비동기 작업은 ‘큐’에 쌓이고 이벤트 루프가 하나씩 처리한다
이벤트 루프를 이해할 때 가장 중요한 개념이 바로 ‘큐(queue)’다. 비동기 작업들은 바로 실행되는 것이 아니라, 일정한 큐에 쌓인다.
예를 들어 서버 요청이나 타이머 같은 작업은 요청을 보낸 뒤 바로 끝나는 것이 아니라, 나중에 결과가 준비되면 큐에 들어간다. 이벤트 루프는 이 큐를 계속 확인하면서, 준비된 작업을 하나씩 꺼내서 실행한다.
이 구조를 처음 이해했을 때 꽤 인상 깊었다. “지금 바로 실행되는 게 아니라, 준비된 순서대로 처리되는구나”라는 느낌이 들었다.
특히 setTimeout 같은 코드를 사용할 때, 시간 설정이 짧아도 바로 실행되지 않는 이유를 이걸 통해 이해하게 됐다. 이벤트 루프가 현재 작업을 끝낸 뒤에야 큐에 있는 작업을 처리하기 때문이다.
즉, 비동기는 무작위로 실행되는 것이 아니라, 이벤트 루프가 정해진 순서에 따라 관리하고 있는 구조다.
그래서 이벤트 루프를 이해하면 비동기 코드가 보이기 시작한다
이벤트 루프 개념을 이해하고 나서 가장 크게 느낀 건, 비동기 코드가 훨씬 덜 헷갈린다는 점이었다. 이전에는 코드 실행 순서가 직관적으로 보이지 않아서 헷갈렸는데, 이제는 “이건 큐로 들어가겠구나”, “이건 나중에 실행되겠구나” 같은 흐름이 조금씩 보이기 시작했다.
특히 웹 개발에서는 이 구조가 거의 기본이라고 해도 될 정도로 많이 사용된다. 버튼 클릭, API 요청, 타이머 같은 모든 비동기 동작이 이벤트 루프를 통해 처리된다.
나도 처음에는 단순히 “비동기니까 빠르다” 정도로만 생각했는데, 실제로는 이런 구조 덕분에 효율적으로 동작하고 있다는 걸 이해하게 됐다.
한 줄로 정리하면 이벤트 루프는 비동기 작업들을 큐에 쌓아두고, 이를 하나씩 꺼내 실행하면서 여러 작업이 동시에 처리되는 것처럼 보이게 만드는 구조다.