Node

[Node.js] Callback Function(콜백 함수)에 대하여 알아보기

YaluStar 2023. 2. 8. 17:23

안녕하세요.

이번에는 Callback Function(콜백 함수)에 대하여 알아보겠습니다.

 

1. 콜백 함수 (Callback Function)

  • Callback : 함수가 끝난 뒤 실행되는 함수
  • 함수를 만들 때 parameter로 함수를 받아서 사용한다.
  • 가독성이나 코드 재사용을 위하여 사용한다.
  • 비동기 방식으로 작성된 함수를 동기 처리하기 위하여 사용한다.

 

먼저 func1() 함수가 있는데 여기서 인자 값으로 첫 번째는 값을 받고 2번째에는 함수를 받습니다.

value = ‘값’, call = 함수

func1() 함수가 실행되면 call()로 2번째 함수를 실행시키고 종료되면 콘솔로 value 값을 출력하는 것이라고 보시면 됩니다.

function func1(value, call) {
    call();
    console.log(value);

}

// 함수 실행
func1('a', function() {
    console.log('1');
});

 

파일을 실행해 보면 콘솔에 1 값이 먼저 찍히고 ‘a’ 값이 나중에 찍힌 것을 볼 수 있습니다.

인자 값을 정리해 보면

value = ‘a’, call = function() { console.log(’1’) }

이라고 보시면 됩니다.

그래서 func1 함수를 실행했을 때 call() 명령어가 먼저 실행돼서

뒤에 console.log(’1’)이 먼저 실행이 된 것이고, 종료 후에

console.log(value)가 실행돼서 다음과 같은 결과가 출력된 것이라고 보시면 됩니다.

 

func1은 동일하고, func2 함수가 추가되었습니다.

여기서 코드를 실행하게 되었을 때는 어떻게 되는지 보겠습니다.

function func1(value, call) {
    call();
    console.log(value);

}

function func2() {
    console.log('2');
}

func1('b', func2);

 

먼저 인자 값은 다음과 같이 들어갑니다.

value = ‘b’ , call = func2()

 

위에서 보았던 결과처럼 func1 함수 내의 call() 명령어가 먼저 실행돼서 func2() 함수가 실행이 되었습니다.

그래서 func2() 함수 내의 console.log(’2’)가 먼저 출력이 되고 func2() 함수 종료 후에

func1() 함수의 console.log(value) 함수가 출력돼서 ‘b’ 값이 나중에 나온 것을 볼 수 있습니다.

 

 

2. 비동기 함수 추가

이번에는 함수에 비동기 함수를 추가한 상태로 코드를 진행해 봅니다.

login 함수 내에 setTimeout() 함수를 넣어 놓고 id를 반환하게 설정하였습니다.

마지막 콘솔에 id가 찍히면 정상 작동인데 확인해 봅니다.

console.log('start');
function login(id, cb) {
    setTimeout(() => {
        console.log('로그인 성공');
        return id;
    }, 2000);
}
const id = login('kim', null);
console.log(id + '님 환영!');
console.log('finish');

 

함수를 실행했더니 id 값을 못 받아서 undefined로 출력이 되었고,

로그인 성공 메시지는 오히려 제일 마지막에 출력이 되었습니다.

 

여기서 문제는 setTimeout 함수 같은 비동기 함수의 존재입니다.

비동기 함수는 다른 명령어의 실행 및 종료되는 거랑은 상관이 없기 때문에 마지막 콘솔에서 id 값을 못 받는 문제가 생깁니다.

 

이제 잘못된 함수를 콜백 함수를 이용하여 정상적으로 고쳐줍니다.

 

이번에는 login 함수를 실행할 때 콜백 함수를 추가하였습니다.

login 함수의 인자 값 cb에 function(id)가 들어가 있고,

cb(id) = function(id) 함수를 호출해서 사용하는 방식입니다.

console.log('start');
function login(id, cb) {
    setTimeout(() => {
        console.log('로그인 성공');
        cb(id);
    }, 2000);
}

login('kim', function(id) {
    console.log(id + '님 환영합니다');
});

console.log('finish');

// login 함수의 cb 에 function(id) 가 들어간거고
// cb(id) = function(id) 함수를 호출해서 한 상태

 

이렇게 설정을 하면 login 함수에서 kim이라는 id를 받아서 console.log(’로그인 성공’) 메시지를 출력한 후 cb(id)로 id 값을 넘겨서 kim님 환영합니다. 메시지를 출력할 수 있게 됩니다.

 

3. 콜백 지옥 ( Callback Hell )

  • 비동기 프로그래밍 시 발생하는 문제
  • 함수의 매개변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여 쓰기가 너무 깊어지는 현상
  • 가독성↓ 코드 수정 난이도↑

 

 

실습코드 - 1

더보기

동기 방식 코드를 비동기 방식으로 고쳐보기

 

  • 동기 방식 코드
// 동기 방식 코드
function login(id, pw, cb) {
    console.log("사용자 입장");
    return id;
}
function getVideo(id, cb) {
    console.log( id + "의 비디오 리스트");
    return ['아바타', '라라랜드'];
}
function getDetail(video, cb) {
    return "비디오 제목 : " + video;
}
let user = login('kim', '1234');
let videos = getVideo(user);
let msg = getDetail(videos[0]);
console.log(msg);
  • 동기 방식 코드 결과

 

 

비동기 방식 코드

// setTImeout() 사용으로 인한 비동기 방식 코드

function login(id, pw, cb) {
    setTimeout(() => {
        console.log('사용자');
        cb(id); // 콜백 함수
    }, 3000);
}
function getVideo(id, cb) {
    setTimeout(function() {
        console.log(id + '의 비디오 리스트');
        cb( ['아바타', '라라랜드']);
    }, 2000);
}
function getDetail(video, cb) {
    setTimeout(() => {
        cb('비디오 제목 : ' + video);
    }, 1000);
}

// 콜백 함수를 이용한 순서 강제 설정
login('kim', '1234', function(user) {
    // console.log(user);
    getVideo(user, function(videos) {
        // console.log('videos : ', videos);
        getDetail(videos[0], function(msg) {
            console.log(msg);
        });
    });
});

 

실습코드 - 2

더보기

 다음 결과와 같이 만들기

call(), 2초 후 실행

back, 1초 후 실행

hell, 0.5초 후 실행

 

// callback 이용한 비동기 방식 실습
// setTImeout() 사용으로 인한 비동기 방식 코드 실습

function call(id, cb) {
    setTimeout(() => {
        console.log('사용자는 ' + id);
        cb('call');
    }, 2000);
}
function back(firstmsg, cb) {
    setTimeout(() => {
        console.log('시작은 ' + firstmsg);
        cb('back');
    }, 1000);
}
function hell(secondmsg, cb) {
    setTimeout(() => {
        console.log('두번쨰는 ' + secondmsg);
        cb('세번째는 hell');
    }, 500);
}


call('kim', function(firstmsg) {
    back(firstmsg, function(secondmsg) {
        hell(secondmsg, function(lastmsg) {
            console.log(lastmsg);
        });
    });
});

 

이상으로 Callback Function에 대하여 알아보았습니다.

감사합니다.

 

반응형