Javscript/동기와 비동기(Synchronous ,Asynchronous)

[Javscript] 콜백함수 (Callback)

Zeta050525 2022. 2. 17. 14:17
728x90

[Javscript] 콜백 함수 (Callback)

Javascript를 사용하다보면 알게 모르게 콜백함수를 사용하고 있습니다.

 

하지만 우리가 처음부터 Javscript를 배울 때 콜백함수가 뭔지 알고 들어가진 않습니다.

 

이름은 모르지만 프로그래밍을 하면서 계속 사용해왔을 겁니다.

 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button>안녕~</button>
  </body>
  <script>
      
    document.querySelector("button").addEventListener("click", () => {
      alert("안녕~");
    });
  </script>
</html>

 

addEventListener("click",callback())

 

이런 식으로 우린 콜백 함수를 사용하고 있었습니다.

 


Callback함수란?

Callback함수는 어떤 함수 안에서 나중에 호출되는 함수입니다.

 

더 간단하고 직관적으로 설명해보면 콜백함수는

 

파라미터로 전달해서 실행시키는 함수다.

 

라고도 말할 수 있습니다.

 

위에서 말씀드렸듯이 우리는 콜백함수를 계속 사용해왔습니다.

 

대표적으로 이벤트 리스너가 있죠

 

    function PleaseCall() {
      alert("나 호출됐엉");
    }

    document.querySelector("button").addEventListener("click", PleaseCall);

이거뿐만이 아니라 Jquery에서도 콜백 함수를 계속 사용해왔고

 

express에서도 app.get("/path",(req,res) => {}) 이런식으로 사용해왔습니다.

 

 

 


Callback함수를 사용하는 이유/ 사용해보기

1. 그냥 코드가 읽고 쉽고 보기 쉽게 하기 위해서

2. 비동기 처리를 위해서

 

class Funcs {
  Login(user, pwd, result) {
    if (user == "Zeta" && pwd == 12345) {
      result("token");
    } else {
      result(new Error("please log in again"));
    }
  }
}

Manager = new Funcs();

Manager.Login("Zeta", 12345, (res) => {
  console.log(res); //token
});

Manager.Login("zz", 33, (res) => {
    console.log(res); //Error: please log in again
  });

이런 식으로 콜백 함수의 인자로 결과를 넘겨줘서 편하게 사용할 수 있습니다.

 


비동기처럼 작동해주라

 

콜백함수를 다루면서 이 글에 동기 비동기까지 다루기엔 너무 길어져서

 

아래 내용들을 이해할 정도로만 설명해보겠습니다.

 

동기 : 코드가 순서대로 작동함

비동기 : 코드가 순서대로 작동하지 않음

 

동기와 비동기 차이를 보면 순서대로 작동하는 동기가 당연히 더 편하고 좋아 보일 테지만

 

동시에 어떠한 작업을 하기 위해 선

 

Javascript는 싱글 스레드이기 때문에 콜백 함수를 이용한 비동기 프로그래밍은 자바스크립트에서 필수적입니다.

 

 

const CallFunction = (callback) => {
  callback()
}

console.log("함수 호출 전")

CallFunction(() => {
  console.log("나 호ㅜㄹ 됐어..")
})

console.log("호출 후")

 

 

이 코드는 동기적으로 작동할까요 비동기적으로 작동할까요?

 

함수 호출 전
나 호출 됐어..
호출 후

 

콜백 함수는 비동기 처리를 위해 사용된다고 했는데 왜 동기적으로 작동할까요?

 

비동기적으로 작동하려면 비동기적으로 콜백 함수를 호출하는 함수에게 함수를 넘겨줘야 합니다.

 


setTimeout(() => {
  console.log("내가 먼저 출력할랭")
}, 1000);

console.log("히히")


//--결과--
//히히
//내가 먼저 출력할랭

 

 

setTimeout함수는 두 번째 인자로 ms를 받습니다 1초 이후에 "내가 먼저 출력할 랭"을 출력하라고 한 거죠

 

여기서 한 가지 이상함 점을 느끼 실수 있습니다. 

 

"Javascript는 싱글 스레드라고 했는 어떻게 타이머 기능을 수행하고 있는 걸까?"

 

setTimeout은 Javascript API에게 시간 카운팅을 위임합니다.

 

그 후 콜백 함수를 메인 스레드에서 실행시킵니다.

 

그럼 이 코드는 어떻게 작동할까요


let article = "Forever Print";

setTimeout(() => {
  article = "Stop!!";
}, 1000);

while (1) {
  console.log(article);
}

Stop이 출력되지 않고 Forever Print가 출력됩니다.

 

왜냐면 메인쓰레드 구조가 스택인데 메인쓰레드에 계속 출력문을 밀어 넣어서

 

1초 이후에도 공간이 없어서 article을 Stop으로 재할당할 수가 없습니다.

 

 

이렇게 콜백함수를 메인 쓰레드에 집어넣어서 실행하기때문에 콜백함수를 사용합니다

728x90