이전에 정리했던 비동기 자바스크립트에 대해 수업이 진행되어 다시 한 번 정리해보고자 한다.
간단하게나마 한 번 익혀두고 수업을 들으니 낯선 느낌도 줄었고 이해도 한결 수월했다.

동기(Synchronous), 비동기(Asynchronous)

동기는 코드가 위에서 아래 순서대로 실행되는 방식이다

console.log("1번 작업");
console.log("2번 작업");
console.log("3번 작업");

이 코드는

1번 작업
2번 작업
3번 작업

이렇게 찍힌 순서대로 실행된다
그러니까, 코드가 순서대로 실행된다는 것은 이전 작업이 끝나야 다음 작업을 실행한다는 점이다.

여기서 발생하는 문제는 앞 작업이 늦게 끝나면 뒤에 간단한 작업이라도 기다려야한다는 점이다


이것을 위해 비동기가 등장했다.

console.log("1번 작업");

setTimeout(() => {
  console.log("2번 작업");
}, 0);

console.log("3번 작업");

이것의 출력은

1번 작업
3번 작업
2번 작업

이렇게 된다. 앞선 코드들의 작업 완료를 순서대로 기다리지 않고, 바로 실행 후 작업 완료 시 콜백 함수를 실행했다.
즉, 비동기 실행은 네트워크 요청이나 파일 처리 같은 시간이 오래 걸리는 작업을 효율적으로 처리할 수 있다


여기서 자바 스크립트에 대해 의문이 생길 수 있다.

자바스크립트는 싱글 스레드인데 어떻게 비동기가 가능할까?

싱글 스레드인 자바스크립트는

한 번에 하나의 작업만 처리할 수 있다.

그런데 비동기가 가능한 이유는 Event Loop 구조 때문이다

자바스크립트 엔진은 실제로는 한 번에 하나의 작업만 처리하지만, 브라우저 환경(Web APIs)이 시간을 오래 사용하는 작업을 대신 처리해 준다.
이것 덕분에 여러 작업을 동시에 처리하는 것처럼 보인다.

Event Loop 간단 흐름

1. 코드 실행
   ↓
2. 비동기 작업 발견
   → 백그라운드로 보냄
   ↓
3. 다음 코드 계속 실행
   ↓
4. 비동기 작업 완료
   → 콜백을 큐에 추가
   ↓
5. 현재 실행 중인 코드가 모두 끝나면
   → 큐에서 콜백 가져와서 실행

예제를 살펴보자

console.log('시작');

setTimeout(() => {
    console.log('타이머');
}, 3000); // 0초 후!

console.log('끝');

// 출력:
// 시작
// 끝
// 타이머

// 왜? 타이머는 비동기라서 큐에 들어갔다가
// 모든 동기 코드가 끝난 후 실행됨

이벤트 루프를 간단하게 살펴보았고, 위 사진은 이벤트 루프 설명을 대표하는 사진이다.
우선 각 용어부터 정리해보자


Call Stack

Call Stack은 현재 실행 중인 코드가 쌓이는 공간이다

앞서 말했듯, 싱글 스레드인 자바 스크립트는 이 스택에 쌓인 작업을 하나씩 순서대로 처리한다.
코드로 살펴보자

function first() {
  console.log("first");
}

function second() {
  first();
}

second();

이 코드가 실행될 때, Call Stack의 흐름은

Call Stack

second()
  ↓
first()
  ↓
console.log()

이처럼 함수가 호출될 때 스택에 쌓이고 실행이 끝나면 제거된다.


Web APIs

Web APIs는 브라우저가 제공하는 기능이다.
대표적인 예로는 setTimeout, DOM 이벤트, fetch(API 요청)이 있다.
이 작업들은 Call Stack에서 바로 실행되는 것이 아니고 Web APIs로 넘어가서 처리된다.

즉, 시간이 오래 걸리는 작업을 브라우저가 대신 처리하는 공간이다


Callback Queue

Web APIs에서 작업이 끝나면
해당 콜백 함수가 Callback Queue로 이동한다.

setTimeout(() => {
  console.log("done");
}, 3000);

이 콜백 함수는 바로 실행이 되는 것이 아닌 Callback Queue에서 대기하고 있는 것이 된다.


Event Loop

자, 다시 이벤트 루프로 돌아와서 보면 결국 이벤트 루프는 이 모든 구조를 관리하는 감시자역할을 하는 것이다.

Call Stack이 비어있는가?
만약 비어있다면
Callback Queue → Call Stack
순서로 콜백 함수를 가져와 실행한다.

전체적인 흐름을 다시 정리해보자면

1. 코드 실행 → Call Stack
2. 비동기 작업 발견 → Web APIs
3. 작업 완료 → Callback Queue
4. Call Stack이 비면
5. Event Loop가 Queue의 콜백을 Stack으로 이동
6. 콜백 실행

이 구조 덕분에 자바스크립트가 싱글 스레드임에도 비동기 처리가 가능한 것이다.

profile
다른 건 노력의 시간

0개의 댓글