< About 동기/ 비동기 ++++++ 2탄>

강민수·2021년 12월 11일
0

백엔드

목록 보기
2/21

이전 시간에는 동기와 비동기 방식에 대한 차이와 비동기 방식의 사용 이유에 대해 한 번 알아봤다. 이번에는 예고처럼... 여러 가지 비동기 처리 방식에 대한 방법들을 알아보려고 한다.

그 첫 번째는 바로 콜백 함수!!!

01. 콜백 함수 (Callback)

01)정의 및 일반적인 활용 예

이름 그대로를 풀어보면 그 의미를 이해할 수 있는 함수다.

콜= 부른다. 백= 뒤에서, 나중에~

그렇다. 순서상 뒤에서 부른다고 해서 콜백인 함수다. 즉, CallBack 함수란 이름 그대로 나중에 호출되는 함수를 말한다. 콜백함수라고 해서 그 자체로 특별한 선언이나 문법적 특징을 가지고 있지는 않다. 콜백함수도 일반적인 자바스크립트 함수일 뿐이다.

콜백 함수는 코드를 통해 명시적으로 호출하는 함수가 아니라, 개발자는 단지 함수를 동록하기만 하고, 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때
시스템에서 호출하는 함수를 말한다.

즉 콜백함수는 콜백함수라는 유니크한 문법적 특징을 가지고 있는 것이 아니라, 호출방식에 의한 구분이다.

대표적인 콜백 함수의 사용 예로는 자바스크립트에서 이벤트 핸들러 처리이다.

<button id="button1" onclick="button1_click();">버튼1</button>
<script>
function button1_click() {
  alert("환영합니다~");
}
</script>

해당 예시를 보면, 버튼을 사용자가 클릭하기 전까지는 함수가 실행되지 않다가, 클릭시에 실행되는 함수가 설정되어 있다. 즉, 버튼을 누르고 나서 실행되는 콜백 함수가 설정되어 있는 것이다.

02) 비동기 방식에서 콜백 방식의 활용 예

우리는 비동기적 프로그래밍을 하기 위해서는, 비동기적으로 콜백함수를 호출하는 함수에게 비동기적으로 호출되기를 원하는 코드를 콜백함수에 담아서 전달해야 한다.

다음 예를 보자~

<script>
function fn_fakeAsync(callback){
  calback();
}

console.log("------- fn_fakeAsync 호출 직전 -------");

fn_fakeAsync(function(){
  console.log("이게 비동기적이 되어야 한다");
});

console.log("------- fn_fakeAsync 호출 이후 -------");
</script>

하지만, 결과는?

------- fn_fakeAsync 호출 직전 -------
이게 비동기적으로 되어야 한다
------- fn_fakeAsync 호출 이후 ------

로 나온다. 이유가 뭘까?
위처럼 단순히 아무 함수에게나 콜백함수를 전달하여 호출시키는 것으로는 비동기적으로 콜백함수를 호출 할수 없다.

즉, 단순한 아무 함수가 아닌 실질적으로 비동기적으로 콜백함수를 호출하는 함수와 비동기적으로 호출되기를 원하는 콜백함수가 필요하다.

그럼 비동기적으로 콜백함수를 실행하는 대표적인 함수들을 알아보자.

03) 대표적인 콜백함수의 종류

1. setTimeout 함수

setTimeout은 콜백함수의 실행을 지정된 밀리초만큼 지연하는 내장함수이다.

<script>
function fn_newCallBack(){
  console.log("비동기로 불러줘! 아버지!");
}

console.log("-------  호출 직전 -------");

setTimeout(fn_newCallBack, 3 * 1000); // 3초 뒤 콜백 호출

console.log("-------  호출 이후 -------");
</script>

------- 호출 직전 -------
------- 호출 이후 -------
비동기적로 불러줘! 아버지!

다음과 같이 3초 후에 호출된 것을 알 수 있다. 여기서 이게 무슨 비동기적 프로그래밍인지 갸웃 할수 있다.

동기적 프로그래밍에서 만약 3초뒤에 fn_newCallBack를 호출시키려 한다면, 3초를 자바스크립트의 하나뿐인 메인스레드가 카운팅을 하고 있어야 한다.
즉 프로그래밍이 멈추는 것이다.

setTimeout함수는 메인스레드가 할일을 자바스크립트 API에게 위임시킴으로써 메인쓰레드의 멈춤(블록킹)을 피하게 해준다.

다음 예제를 보자.

<script>
function fn_newCallBack(){
  console.log("비동기적으로 이번엔 1빠?");
}

console.log("-------  호출 직전 -------");

setTimeout(fn_newCallBack, 0); // 0초니까 1빠?

console.log("-------  호출 이후 -------");
</script>

------- 호출 직전 -------
------- 호출 이후 -------
비동기적으로 이번엔 1빠?

오잉? 이게 어캐 된 일일까? 결과가 똑같다. 그렇다. 셋타임아웃은 이렇게 지연초를 조절은 할 수 있지만, 결국 비동기적인 함수이기 때문에 실행 순서에서는 바뀌지 않는다. 이에 대해서는 후에 왜 그런지 eventloop 작동 원리와 묶어서 설명하겠다.

02.setInterval함수와 clearInterval함수

setInterval도 setTimeout과 같이 콜백을 비동기적으로 호출 가능하게 해주는 함수이다.
차이점은 지정된 시간을 기준으로 반복적으로 콜백을 호출해준다는 것이다.

<script>
let i = 0;
const intervalId = setInterval(function(){
  
  if(i === 3) return clearInterval(interbalId);

  console.log(`${i++}: 인터벌 호출.`);
  
}, 5 * 1000);
</script>

setInterval의 기능은 단순하다 중요한 것은 고유의 intervalId를 리턴하고 이것을 clearInterval 함수에 넘겨 해당 setInterval을 중지시킬수 있다. 특시 Node등 서버단에서 setInterval를 사용할 경우 반드시 clearInterval로 인터벌을 정지시키지 않을경우 서버 메모리 누수가 발생할 수도 있으니 주의해야 한다.

지금까지 setTimeout, setInterval, clearInterval등은 모두 전역 객체(브라우저에서는 Window, 노드에서는 global)에 정의 되어 있으므로 어디서나 사용할 수 있다.

하지만, 이런 콜백 함수로 쓰는 것에도 문제점은 분명 존재한다. 그래서 태어난 것들이 있는데... 다음 시간에는 콜백의 기능들을 보완하기 위해 태어난 것들에 대해 한 번 알아보겠다.

---------------------to be continued---------------------------

profile
개발도 예능처럼 재미지게~

0개의 댓글