[JavaSciprt] 콜백 함수(Callback Function)

워네·2022년 5월 16일
0

🌙 JavaScript

목록 보기
1/4
post-thumbnail

📌 콜백함수(Callback Function) 란?

파라미터로 함수를 전달하는 함수

콜백함수란 파라미터로 함수를 전달받아, 함수의 내부에서 실행하는 함수이다.

let number = [1, 2, 3, 4, 5];

number.forEach(x => {
    console.log(x * 2);
});

<output>
2
4
6
8
10

콜백함수는 이미 우리의 코드 속에서 자주 사용되고 있다.
예를 들어, forEach 함수의 경우 함수 안에 익명의 함수를 넣어서 forEach 문을 동작시킨다.


📖 콜백함수(Callback Function) 사용 원칙

  • 익명의 함수 사용
let number = [1, 2, 3, 4, 5];

number.forEach(function(x) {
    console.log(x * 2);
});

위의 예제를 화살표 함수에서 일반 함수로 바꾼 예제이다.
콜백함수는 이름이 없는 익명의 함수를 사용한다.
함수의 내부에서 실행되기 때문에 이름을 붙이지 않아도 된다.


📖 함수의 이름(만) 넘기기

function whatYourName(name, callback) {
    console.log('name: ', name);
    callback();
}

function finishFunc() {
    console.log('finish function');
}

whatYourName('miniddo', finishFunc);

<output>
name: miniddo
finish function
TIP ✨

JavaScript Data Type
- number, string, boolean, object(function, array, data, regexp), null, undefined

자바스크립트는 null과 undefined 타입을 제외하고 모든 것을 객체로 다룬다. 함수를 변수 or 다른 함수의 변수처럼 사용할 수 있다. 함수를 콜백함수로 사용할 경우, 함수의 이름만 넘겨주면 된다. 위의 예제에서, 함수를 인자로 사용할 때 callback, finishFunc 처럼 () 를 붙일 필요가 없다는 것이다.

📖 전역변수, 지역변수 콜백함수의 파라미터로 전달 가능

  • 전역변수(Global Variable) : 함수 외부에서 선언된 변수
    ex) let fruit = 'apple'; // Global Variable

  • 지역변수(Local Variable) : 함수 내부에서 선언된 변수

function callbackFunc(callback) {
    let vegetable = 'tomato';	// Local Variable
    callback(vegetable);
}

function eat(vegetable) {
    console.log(`fruit: ${fruit} / vegetable: ${vegetable}`);
}

callbackFunc(eat);

<output>
fruit: apple / vegetable: tomato

📖 콜백함수(Callback Function) 주의할 점

let userData = {
    signUp: '2022-05-16 15:00:00',
    id: 'dnjsp',
    name: 'Not Set',
    setName: function(firstName, lastName) {
        this.name = firstName + ' ' + lastName;
    }
}

function getUserName(firstName, lastName, callback) {
    callback(firstName, lastName);
}

getUserName('JO', 'WONHYE', userData.setName);

console.log('1: ', userData.name);
console.log('2: ', window.name);

<output>
1: Not Set
2: JO WONHYE

첫번째 콘솔에서 JO WONHYE가 출력되길 원했지만, Not Set이 출력된다.
setName()함수가 실행되기 전의 name 값이 나오는데, 이는 getUserName()이 전역 함수이기 때문이다.

즉, setName()에서 사용된 this 객체가 window라는 글로벌 객체를 가리킨다.
따라서 this를 보호할 수 있는 콜백함수를 만들어야 한다.

해결 방안: call()apply()를 사용하여 this를 보호할 수 있다.

  • call(): 첫 번째 인자로 this 객체 사용, 나머지 인자들은 , 로 구분
  • apply(): 첫 번째 인자로 this 객체 사용, 나머지 인자들은 배열 형태로 전달
// call

let userData = {
    signUp: '2022-05-16 15:00:00',
    id: 'dnjsp',
    name: 'Not Set',
    setName: function(firstName, lastName) {
        this.name = firstName + ' ' + lastName;
    }
}


function getUserName(firstName, lastName, callback, obj) {
  	callback.call(obj, firstName, lastName);	(1)
}

getUserName('JO', 'WONHYE', userData.setName, userData);	(2)

console.log(userData.name);

// JO WONHYE

(2)에서 마지막 인자에 담긴 userData는 (1)에서 call함수의 첫번째 인자로 전달된다.
즉, call()에 의해서 userDatathis 객체가 매핑된다.


📖 콜백지옥

비동기 호출이 자주 일어나는 프로그램의 경우 '콜백 지옥'이 발생한다.
함수의 매개변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여쓰기 수준이 감당하기 힘들어질 정도로 깊어지는 현상이다.

function add(x, callback) {
    let sum = x + x;
    console.log(sum);
    callback(sum);
}

add(2, function(result) {
    add(result, function(result) {
        add(result, function(result) {
            console.log('finish!!');
        })
    })
})
/*
4
8
16
finish!!
*/

해결방안: Promise를 사용하여 콜백지옥을 탈출한다.

profile
front-end developer 🐣

0개의 댓글