Skip to main content

2. Callback 함수


1. 콜백함수(Callback)

콜백 함수란?

콜백 함수는 다른 함수에 인수로 전달되어, 특정 작업이 끝난 후 호출되는 함수를 말한다.

function sayHello() {
  console.log("Hello!");
}

function executeCallback(callback) {
  console.log("Before callback");
  callback(); // 콜백 함수 호출
  console.log("After callback");
}

executeCallback(sayHello);

<실행흐름>

  1. executeCallback 함수가 호출되면, sayHello 함수가 콜백 함수로 전달
  2. console.log("Before callback")이 실행
  3. sayHello()가 실행되면서 "Hello!"가 출력
  4. console.log("After callback")이 실행

<출력결과>

Before callback
Hello!
After callback


2. 콜스택(Call Stack) 이란?

콜 스택(Call Stack)

콜 스택은 현재 실행 중인 함수와 대기 중인 함수들을 저장하는 구조이다.

자바스크립트는 코드를 실행할 때, 함수 호출이 발생하면 이를 콜 스택에 쌓고, 실행이 끝나면 콜 스택에서 제거한다.

간단하게 비유하면 콜 스택은 접시를 쌓는 스택처럼 동작한다. 함수가 호출되면 접시를 쌓듯이 위에 추가되고 함수 실행이 끝나면 위에서 제거된다.


3. 콜백 큐(Callback Queue)란?

콜백 큐(Callback Queue)

콜백 큐는 비동기 작업이 완료된 후 실행할 콜백 함수들이 대기하는 장소이다.

콜백 큐에 있는 함수는 이벤트 루프가 콜 스택이 비었을 때 가져와 실행한다.

console.log("Start");

setTimeout(() => {
  console.log("Timeout callback");
}, 1000);

console.log("End");

<실행 흐름>

  1. console.log("Start") 실행 → "Start" 출력
  2. setTimeout 호출 → 비동기 함수로 동작 → 콜백 함수는 콜백 큐에 저장
  3. console.log("End") 실행 → "End" 출력
  4. 1초 후, 콜백 큐에 있던 함수가 콜 스택으로 이동 → "Timeout callback" 출력

<출력 결과>

Start
End
Timeout callback


4. 이벤트 루프

콜 스택과 콜백 큐의 관계

동작 원리

콜 스택이 비어 있으면, 이벤트 루프가 콜백 큐를 확인

콜백 큐에 대기 중인 함수가 있다면 이를 콜 스택으로 이동시켜 실행


콜백 함수 + 콜백 큐 + 콜 스택 예제

console.log("Start");

setTimeout(() => {
  console.log("Callback 1");
}, 1000);

setTimeout(() => {
  console.log("Callback 2");
}, 500);

console.log("End");

<실행 흐름>

  1. console.log("Start") 실행 → 콜 스택에서 실행 후 제거 → "Start" 출력
  2. setTimeout 호출 → 비동기 함수로 콜백을 콜백 큐에 등록 (500ms와 1000ms)
  3. console.log("End") 실행 → 콜 스택에서 실행 후 제거 → "End" 출력
  4. 500ms 후, 첫 번째 콜백 함수(Callback 2)가 콜백 큐에서 콜 스택으로 이동 → 실행 후 제거 → "Callback 2" 출력
  5. 1000ms 후, 두 번째 콜백 함수(Callback 1)가 콜백 큐에서 콜 스택으로 이동 → 실행 후 제거 → "Callback 1" 출력

<출력 결과>

Start
End
Callback 2
Callback 1


# 요약

위에서 정리한 내용을 간단 요약함

1. 콜 스택(Call Stack)

JavaScript는 싱글 스레드 기반으로 동작하며, 현재 실행 중인 코드와 함수 호출은 콜 스택(Call Stack)에 추가됨. 즉 콜 스택에는 현재 실행중인 함수와 대기 중인 함수가 쌓이고 제거된다.

2. 콜백 큐(Callback Queue)

콜백 큐는 비동기적으로 실행되는 작업(예: setTimeout, Promise)이 완료된 후 콜 스택에 추가될 준비가 된 작업들을 관리한다. 즉, 콜백큐는 비동기 함수의 콜백이 대기하는 장소이고 콜 스택이 비면 실행된다. 그렇기 때문에 동기 함수만 사용하는 코드에는 콜백 큐와 이벤트 루프가 관여하지 않는다.

3. 이벤트 루프(Event Loop)

이벤트 루프는 콜 스택이 비어 있는지 확인한 후, 콜백 큐에서 대기 중인 작업을 콜 스택으로 이동시킨다.

4. 콜백함수(Callback 함수)

다른 함수에 전달되어 특정 작업이 끝난 후 실행되는 함수.


# 예시코드

콜스택 예제

function asd(asdf, callback) {
  console.log("a");
  callback(); // sdf() 호출
  console.log("b");
}

function sdf() {
  console.log("c");
}

asd("name", sdf); // 호출

실행 흐름(콜 스택)

asd("name", sdf) 호출: 함수 asd 콜스택 추가 -> console.log("a") 실행: "a" 출력 -> 실행 후, console.log는 콜 스택에서 제거

callback() 호출: callback()은 전달받은 sdf 함수이기 때문에 sdf() 실행 -> sdf 함수가 콜 스택에 추가 -> sdf 함수 내부의 console.log("c")가 실행되어 "c"가 출력됨. ->실행 후, sdf는 콜 스택에서 제거됨.

다시 asd 함수로 돌아와 console.log("b")가 실행됨. -> "b" 출력 -> console.log("b")는 콜 스택에서 제거 -> asd 함수의 실행이 완료되어 콜 스택에서 제거

<출력결과>

a
c
b

콜백 큐는 비동기 함수(setTimeout, Promise.then, fetch)에 의해 생성된 작업을 처리하는 구조이기 때문에 이 코드의 모든 함수는 동기적으로 실행된다. 따라서, 콜백 큐와 이벤트 루프는 작동하지 않고 콜 스택만으로 모든 작업이 처리된다.


콜 스택 상태 변화

asd 호출

asd

console.log("a") 실행

asd
console.log

sdf 호출

asd
sdf

console.log("c") 실행

asd
sdf
console.log

sdf 완료 → console.log("b") 실행

asd
console.log

asd 완료

(빈 상태)