오답노트 및 하다 막힌 부분/Javascript

24/11/15 막힌 키워드 - 콜백함수

Dr.Mlem 2024. 11. 15. 22:40

JS의 콜백함수

 

Q.
JS에서 콜백함수라고 있었는데, 콜백함수가 파라미터로 쓰이기 위한 함수라고 하면 맞아?
 
 
 
A.
네, 맞습니다! 콜백 함수는 다른 함수의 파라미터로 전달되는 함수를 의미합니다. 이 함수는 나중에, 즉 호출된 함수의 내부에서 특정 시점에 실행됩니다. 이를 통해 함수 간의 협력과 비동기 작업을 효율적으로 처리할 수 있습니다.

콜백 함수의 특징

  1. 함수로 전달됨: 콜백 함수는 보통 다른 함수에 인자로 전달됩니다.
  2. 필요한 시점에 호출: 전달된 콜백 함수는 특정 조건이 만족되거나 작업이 완료된 시점에 호출됩니다.
  3. 함수 정의의 유연성: 콜백 함수는 다른 함수 내부에서 실행 로직을 외부에서 정의할 수 있도록 도와줍니다.

간단한 예제

function greet(name, callback) {
    console.log("Hello, " + name);
    callback();
}

function sayGoodbye() {
    console.log("Goodbye!");
}

// sayGoodbye를 콜백 함수로 전달
greet("Alice", sayGoodbye);

// 출력:
// Hello, Alice
// Goodbye!

 

실제 활용 예: setTimeout

JavaScript에서 콜백 함수의 대표적인 활용 예는 비동기 함수입니다. 예를 들어, setTimeout 함수는 콜백 함수를 실행하기 위해 사용됩니다.

 

setTimeout(() => {
    console.log("1초 뒤에 실행됩니다!");
}, 1000); // 1000ms = 1초

 

여기서 setTimeout의 첫 번째 파라미터로 전달된 익명 함수 () => {...}가 콜백 함수입니다. 이 함수는 1초가 지나면 실행됩니다.

 

콜백이 필요한 이유

  1. 비동기 처리: JavaScript는 싱글 스레드 언어라서 블로킹 작업을 피하기 위해 비동기 작업이 필요합니다. 콜백은 이러한 비동기 작업의 결과를 처리하는 데 효과적입니다.
  2. 코드 재사용성: 함수의 동작을 외부에서 제어할 수 있어 더 유연한 코드 작성이 가능합니다.

정리

  • 콜백 함수는 다른 함수의 파라미터로 전달되며, 전달된 함수의 내부에서 호출됩니다.
  • 동기/비동기 작업을 처리하는 데 유용합니다.

 



..... 좀 더 질문한 과정이 있었으나, 생략

 

 


Q2.
콜백 함수를 쓰는 구조 자체가, 어떤 함수를 또 다른 함수 안에서 쓰고 싶기에, 일단 함수의 이름만을 파라미터로 받고,

그 함수의 기능을 또 다른 함수 안에서는 함수로서 작동하게 하려다보니,

functionA(functionB){
functionB();
}

꼴로 작성이 된다는 거야?



A2.

네, 정확히 이해하셨어요! 👏

콜백 함수를 쓰는 구조 자체는 다른 함수 안에서 특정 작업을 실행하거나, 어떤 조건에 따라 호출될 수 있도록 유연하게 처리하기 위해 만들어진 구조입니다. 다시 말해, 함수 A(예: functionA)가 함수 B(예: functionB)를 "콜백"으로 받아서, 특정 시점에 functionB()를 호출하는 구조라고 보면 됩니다.

더 간단히 표현하면:

  1. 함수 이름만 전달: functionB는 함수의 "참조"로 전달됩니다. 즉, 이름만 넘기는 것이죠.
  2. 내부에서 실행: functionA는 전달받은 functionB를 필요한 시점에 호출(예: functionB())합니다.

 

구조의 기본 형태

function functionA(callback) {
    // 다른 작업을 수행하다가...
    callback(); // 전달받은 콜백 함수를 실행
}

function functionB() {
    console.log("Hello, I am functionB!");
}

functionA(functionB);
// 출력:
// Hello, I am functionB!

 

  • functionA는 functionB를 파라미터로 받고, 전달된 functionB를 함수처럼 호출(callback())합니다.
  • 이 방식은 함수가 즉시 실행되지 않고, 제어권을 functionA 내부에서 가지고 있다가 필요할 때 호출할 수 있게 만듭니다.

왜 이렇게 설계했을까?

콜백 함수 구조가 필요한 이유는 크게 두 가지로 볼 수 있습니다:

  1. 유연한 실행 제어:
    • functionA가 어떤 작업을 마치고 나서 functionB를 호출해야 할 수도 있습니다.
    • 예를 들어, 데이터를 처리한 뒤에, 또는 조건이 충족되었을 때 functionB를 실행할 수 있죠.
  2. 재사용성:
    • 여러 종류의 콜백 함수를 functionA에 전달할 수 있어서, functionA의 동작을 유연하게 변경할 수 있습니다.

 

 

실생활 예제: 이벤트 처리

콜백 함수는 이벤트 기반 프로그래밍에서 자주 사용됩니다. 예를 들어, 사용자가 버튼을 클릭했을 때 실행되는 코드를 작성할 때:

function handleClick() {
    console.log("Button was clicked!");
}

// 버튼 클릭 시 실행될 함수(handleClick)를 콜백으로 전달
document.getElementById("myButton").addEventListener("click", handleClick);

여기서 addEventListener는 내부적으로 handleClick을 콜백으로 받아서, 버튼이 클릭될 때 호출합니다.

 

비유로 이해하기

콜백 함수 구조를 쉽게 이해하려면 다음 비유를 생각해 보세요:

  • functionA는 요리사입니다.
  • functionB는 요리사에게 전달된 요리 레시피입니다.
  • 요리사는 레시피를 받아서, 필요한 시점에 그 레시피를 따라 요리를 만듭니다.
function chef(recipe) {
    console.log("요리 시작!");
    recipe(); // 레시피에 따라 요리 실행
    console.log("요리 완료!");
}

function recipe() {
    console.log("이 레시피는 파스타를 만듭니다!");
}

chef(recipe);
// 출력:
// 요리 시작!
// 이 레시피는 파스타를 만듭니다!
// 요리 완료!

 

다시 정리

  • 콜백 함수 구조는 다른 함수의 제어권을 넘겨주고, 특정 시점에 원하는 작업을 실행할 수 있게 하는 방식입니다.
  • functionA(functionB)의 형태로 작성되는 이유는:
    1. 함수의 참조를 파라미터로 전달하기 위해서.
    2. 전달받은 함수를 필요한 시점에 호출하기 위해서.

이 방식은 특히 비동기 작업(예: 파일 읽기, 네트워크 요청 등)과 이벤트 처리에서 매우 유용합니다. 😊




Q3.

만약,

 

functionA(functionB()){

functionB();

}

 

꼴로 작성되면 어떻게 되는거야?

 

 

 

A3.

좋은 질문입니다!

만약 functionA(functionB())처럼 함수 호출 결과를 전달하려 한다면, 이 경우 functionB()는 이미 실행된 뒤, 그 반환값이 functionA의 파라미터로 전달됩니다. 즉, 콜백 함수로 전달되지 않고, 실행 결과(리턴값)만 전달되기 때문에 의도한 대로 작동하지 않을 수 있습니다.

 

예제 코드로 확인

function functionA(callback) {
    console.log("Inside functionA");
    console.log(callback); // callback에 전달된 값 출력
}

function functionB() {
    console.log("Inside functionB");
    return "Result from functionB";
}

// functionB() 호출한 결과를 functionA에 전달
functionA(functionB());

 

실행 결과:

Inside functionB  // functionB가 먼저 실행됨
Inside functionA
Result from functionB  // functionB의 반환값이 callback으로 전달됨

설명

  1. functionB()를 작성했기 때문에 functionA가 호출되기 전에 functionB가 먼저 실행됩니다.
    • 이로 인해, functionB 내부의 작업이 즉시 수행됩니다.
    • 그리고 functionB의 반환값("Result from functionB")이 functionA의 파라미터로 전달됩니다.
  2. functionA 내부에서는 더 이상 functionB를 콜백으로 사용할 수 없고, 단순히 반환된 문자열 "Result from functionB"를 값으로 다루게 됩니다.

의도와 다르게 동작할 수 있음

콜백 함수는 "함수를 나중에 호출하려고" 전달하는 구조입니다. 하지만 functionB()처럼 즉시 호출해버리면, 나중에 사용할 수 있는 함수 자체가 아니라, 함수의 실행 결과만 전달됩니다.

이 경우, 원하는 시점에 다시 functionB를 실행할 수 없으므로, 콜백 함수의 본래 목적과 다르게 동작하게 됩니다.

 

올바른 사용 방법

콜백 함수로 전달하려면 함수 이름(참조)만 전달해야 합니다

function functionA(callback) {
    console.log("Inside functionA");
    callback(); // 여기서 전달된 콜백 함수를 실행
}

function functionB() {
    console.log("Inside functionB");
}

functionA(functionB);

 

실행 결과:

Inside functionA
Inside functionB

 

결론

functionA(functionB())를 쓰면 functionB가 즉시 실행되고, 그 반환값이 functionA에 전달됩니다. 만약 콜백 함수로 전달하고 싶다면, 함수 이름만 전달해야 합니다.

 

즉, 올바른 형태는:

functionA(functionB);

 

 

일단 이걸로 일단락...