프로그래밍 & IT 정보/Javascript

자바스크립트 콜백 함수 예제를 통해 개념 및 원리 쉽게 이해하기

아미넴 2020. 12. 1.
반응형

자바스크립트를 배운 지 얼마 안 되신 분이라면 콜백 함수를 많이 헷갈려 하실 수 있는데요.

차근차근 설명을 해 보도록 하겠습니다.

 

목차

     

    동기와 비동기 의미

    동기는 하나의 요청이 오면 완료가 된 후 다음 요청을 실행하는 방식을 말하고

    비동기는 어떤 요청이 오면 완료가 되기 전에 다음 요청을 실행하는 방식을 말합니다.

     

    동기 방식은 순차적으로 로직이 수행되므로 흐름을 쉽게 예측할 수 있지만,

    비동기 방식의 경우 여러 작업을 동시에 효율적으로 처리할 수 있는 반면에

    즉시 응답을 못받기 때문에 적절히 처리가 되지 않으면

    예상 밖의 결과가 나올 수 있으므로 주의를 기울여야 합니다.

     

    콜백 함수 사용 목적

    비동기 방식으로 작성된 함수를 동기 처리 하기 위해 주로 사용합니다.

    비동기 처리를 기본으로 하면서도 일부 구간에서 순차적인 처리가 필요할 수도 있기 때문입니다.

     

    다르게 말하면 독립적으로 수행되는 작업도 있는 반면 응답을 받은 이후 처리되어야 하는 종속적인 작업도 있을 수 있으므로 그에 대한 대응 방법이 필요한 것입니다.

     

    콜백 함수 형태

    function mainFunc(param1, param2, callbackFunc) {
        // ... 처리 내용 작성
        callbackFunc(result);
    }

    보통 함수를 선언한 뒤에 함수 타입 파라미터를 맨 마지막에 하나 더 선언해 주는 방식으로 정의합니다.

    처리가 끝나면 파라미터로 전달 받은 함수를 실행합니다.

    필요한 경우 결과 값을 인자로 넘겨줄 수도 있습니다.

     

    순차 흐름 작성 예제

    물건을 구매하는 프로세스를 예시로 들어보겠습니다.

    function buy_normal(item, price, quantity) {
        console.log(item + " 상품을 " + quantity + "개 골라서 점원에게 주었습니다.");
        console.log("계산이 필요합니다.");
        var total = price*quantity;
        return total;
    }
    
    function pay(tot) {
        console.log(tot + "원을 지불하였습니다.");
    }

    먼저 물건을 하나 골라서 점원에게 줍니다.

    계산이 필요하다는 메시지를 띄우고 총액을 구합니다.

    그리고 구한 총액을 리턴합니다.

    그리고 지불을 하는 함수도 하나 만들었습니다.

     

    함수를 실제로 호출해 보겠습니다.

    var tot = buy_normal("고구마", 1000, 5);
    pay(tot);

    1개에 1000원인 고구마를 5개 샀습니다.

    총 금액을 리턴하는 함수이므로 tot 변수에 대입을 시켜 주었습니다.

    그리고 그 금액을 지불하는 함수도 호출하였습니다.

     

    동기 방식은 순차 처리를 하므로 예상과 동일한 결과를 얻을 수 있습니다.

    기초적인 방법으로 작성한 소스는 대부분 동기 방식이라고 볼 수 있습니다.

     

    잘못 처리된 비동기 방식 예제

    그럼 물건 구매 프로세스를 조금 바꿔보겠습니다.

    function buy_asis(item, price, quantity) {
        console.log(item + " 상품을 " + quantity + "개 골라서 점원에게 주었습니다.");
        setTimeout(function() {
            console.log("계산이 필요합니다.");
            var total = price*quantity;
            return total;
        }, 1000);
    }

    물건을 하나 골라서 점원에게 주고 총액을 구하고 계산이 필요하다는 메시지를 띄우는 것까지는 동일합니다.

    여기에 점원이 물건을 받아서 계산하는 동안은 시간이 필요하다는 가정을 추가하였습니다.

    setTimeout 함수를 사용하여 1초 뒤에 계산이 완료된다고 생각하겠습니다.

    var tot = buy_asis("고구마", 1000, 5);
    pay(tot);

    1개에 1000원인 고구마를 5개 사서 총 금액을 리턴하여 tot 변수에 대입을 시켜 주었습니다.

    그리고 동일하게 tot를 지불 함수의 파라미터로 넘겨 주었습니다.

     

    어떤가요?

    예상했던 것과는 결과가 많이 다릅니다.

    총액은 undefined 이고 1초 후 계산이 필요하다는 메시지가 출력되었습니다.

     

    왜 이런 결과가 나온 걸까요?

     

    setTimeout 함수는 순차적인 흐름을 보장하지 않는 비동기 방식의 대표적인 예입니다.

     

    setTimeout 함수를 호출하고 1초 뒤에 다음 구문이 실행되는 것이 아니라

    호출한 직후 바로 다음 구문을 실행하기 때문이죠.

    따라서 setTimeout 함수 내 메시지 출력과 리턴 구문은 1초 뒤에 실행이 될 것이고

    tot 변수에 아무 값도 받지 못한 상태로 지불 메시지가 먼저 출력되었습니다.

     

     

    콜백 함수를 이용한 올바른 동기 처리

    이제 콜백 함수가 필요한 이유가 명확해 집니다.

    function buy_tobe(item, price, quantity, callback) {
        console.log(item + " 상품을 " + quantity + "개 골라서 점원에게 주었습니다.");
        setTimeout(function() {
            console.log("계산이 필요합니다.");
            var total = price*quantity;
            callback(total);
        }, 1000);
    }

    총액을 계산한 이후의 행위를 기술하기 위해 콜백 함수를 인자로 받고 setTimeout 함수 내에 포함시켰습니다.

    계산이 필요하다는 메시지 이후에 콜백 함수를 수행하므로 콜백 함수에 지불 내용을 기술하면

    우리가 원하는 순서로 진행이 가능해 보입니다.

     

    이제 지불 함수를 콜백 파라미터에 대입해 보겠습니다.

    buy_tobe("고구마", 1000, 5, pay);

     

    예상대로 정상적인 순서로 메시지가 출력되는 것을 볼 수 있습니다.

    두 번째 메시지는 1초 뒤에 출력이 되고 이어서 세 번째 메시지도 출력이 됩니다.

    이로써 순차 실행을 만족하게 되었습니다.

     

    pay 함수를 따로 선언하지 않고 바로 익명함수 처리도 가능합니다.

    buy_tobe("고구마", 1000, 5, function(tot) {
        console.log(tot + "원을 지불하였습니다.");
    });

    구조가 눈에 익지 않는다면 파악하기 위해 노력하는 것이 중요합니다.

     

     

    추가 사항

    콜백 함수는 비동기로 작성된 함수를 동기 처리하기 위한 하나의 방법론이며 실제로 많이 쓰이고 있습니다.

     

    다만 콜백 함수를 너무 많이 중첩하면 콜백 지옥에 빠질 수 있으므로

    공부와 연습을 통해 적절히 이용을 할 수 있어야 합니다.

    librewiki.net/wiki/%EC%BD%9C%EB%B0%B1_%EC%A7%80%EC%98%A5

     

    콜백 지옥

    callback hell

    librewiki.net

     

    좀 더 발전된 방법으로 비동기 방식을 처리할 수 있는 Promise에 대한 포스팅도 참고 바랍니다 :)

    sangminem.tistory.com/284

     

    [자바스크립트] Promise 예제를 통해 쉽게 이해하기

    비동기 처리의 한 방법인 콜백 함수를 다루면서 동기와 비동기에 대한 개념도 함께 설명을 드렸는데요. 잘 모르시는 분은 아래 포스팅 먼저 읽어 보시길 바랄게요 :) sangminem.tistory.com/275 [자바스

    sangminem.tistory.com

     

    감사합니다.

    반응형

    댓글

    💲 추천 글