본문 바로가기

JavaScript

[JavaScript] 이벤트 루프, 콜백 함수

자바스크립트의 특징

  • 자바스크립트는 단일 스레드 기반의 언어로 한 번에 하나의 작업만을 처리할 수 있다.
  • 비동기로 동작하기 때문에 단일 스레드임에도 동시에 많은 작업을 수행한다.
  • 하지만 비동기로 동작하는 핵심 요소는 자바스크립트가 아닌 브라우저가 가지고 있다.

이벤트 루프란?

  • 태스크가 들어오길 기다렸다가 태스크가 들어오면 이를 처리하고, 처리할 태스크가 없는 경우엔 잠드는, 끊임없이 돌아가는 자바스크립트 내 루프

자바스크립트의 동작 과정

  • Heap : 메모리 할당이 발생하는 곳
  • Call Stack : 실행된 코드의 환경을 저장하는 자료구조로, 함수 호출 시 이곳에 저장된다. 어떤 함수를 저장하면 스택에 쌓고 또 다른 함수를 호출하면 그 다음 스택에 쌓이면서 가장 위에 쌓인 함수를 가장 먼저 처리한다. LIFO(Last In First Out)
  • Web APIs : Web API는 브라우저에서 제공하는 API로 DOM, Ajax, TimeOut 등이 있다.
    CallStack에서 실행된 비동기 함수는 Web API를 호출하고, Web API는 콜백 함수를 Task Queue에 넣는다.
  • Callback Queue : 함수를 저장하는 자료구조로, Call Stack과 다르게 가장 먼저 들어온 함수를 가장 먼저 처리한다.
  • Event Loop : 이벤트 루프는 call stack이 다 비워지면 callback queue에 존재하는 함수를 하나씩 call stack으로 옮기는 역할을 한다.

콜백 함수

  • 자바스크립트에서 함수는 객체로 함수의 파라미터로서 객체를 전달할 수 있다.
  • 어떤 함수에서 다른 함수를 파라미터로 받아서 내부에서 그것을 호출 할 수 있는데
    다른 함수의 파라미터로써 전달되는 함수를 콜백 함수라고 한다.
function print(callback) {
    callback();
}

콜백 함수가 필요한 이유

  • 자바스크립트는 기본적으로 코드를 위에서 아래로 실행한다. 그러나 코드가 다른 행위가 일어난 뒤에 실행되거나 순차적으로 실행되지 않을 때도 있다. 이것을 비동기 프로그래밍이라고 한다.
  • 콜백은 작업이 끝나기 전에 함수가 실행되지 않는 것을 보장한다. 콜백은 비동기 자바스크립트 코드를 작성할 수 있게 해주고 각종 문제와 에러를 방지한다.

콜백 함수는 어떻게 사용하나요?

setTimeout 함수

const message = function() {
    console.log("This message is shown after 3 seconds");
}
setTimeout(message, 3000);

setTimeout 함수는 자바스크립트에 내장된 함수로 주어진 시간 이후에 함수를 호출합니다. (ms단위로 1000ms = 3초)

여기서 message 함수는 어떤일이 일어나기 전이 아닌 뒤에(3초뒤) 호출됩니다.

함수 내부에 직접 정의

setTimeout(function() {
    console.log("This message is shown after 3 seconds");
}, 3000);

여기서 콜백 함수는 이름이 없고 자바스크립트에서 이름이 없는 함수 정의를 "익명 함수"라고 합니다. 이 함수는 위의 함수와 같이 작동합니다.

화살표 함수 모양의 콜백

setTimeout(() => {
    console.log("This message is shown after 3 seconds");
}, 3000);

위의 함수와 같은 동작을 하는 함수를 화살표 함수로도 사용할 수 있습니다.

이벤트 정의

자바스크립트는 이벤트 기반 프로그래밍 언어로 콜백 함수를 이벤트 선언을 위해 사용하기도 한다.

<button id="callback-btn">Click here</button>

사용자가 버튼을 클릭할 때 콘솔에 메세지 남기기

document.queryselector("#callback-btn")
    .addEventListener("click", function() {
      console.log("User has clicked on the button!");
});

1. 버튼의 id값을 사용하여 버튼을 선택

2. addEventListener 메소드를 사용하여 이벤트 리스너를 추가

3. 이벤트 리스너 함수는 두 개의 파라미터가 필요한데 첫 번째 파라미터는 이벤트의 타입인 "click"이고
    두 번째 파라미터는 버튼이 클릭 되었을 때 메세지를 남기는 콜백 함수다.