[JavaScript] 비동기 처리 - 콜백 함수

 

 

앞서 비동기 처리의 동작 원리와 동기적 처리 과정의 단점을 어떻게 해결하는지 알아보았었다.

하지만, 비동기 처리는 시간 낭비 없이 동시에 여러 기능을 수행할 수 있게 하지만, 실행 결과의 순서가 보장되지 않는 문제점이 있었다.

이를 해결하기 위한 방법 중 하나로 콜백 함수에 대해 알아보겠다.

 

 

콜백 함수 (Callback)

콜백 함수란 다른 하수에 인수 혹은 매개변수로 넘겨지는 함수이다.

함수의 실행이 끝나면 지정한 콜백 함수를 실행해주도록 함수에 요청할 때 사용한다.

즉, 이벤트가 발생하거나 특정 시점에 실행되는 함수를 말한다.

 

function example(callback, ...){
  callback();
}

example(call, ...);

위 코드는 callback함수의 매우 기초적인 사용 예시이다. 위 코드에서는 call이 콜백 함수이다.

example() 함수는 매개변수로 callback인 또 다른 함수를 받고 있으며, 이 함수는 example 함수 내부에서 호출되고 있다.

이때 example() 함수에 매개변수로 전달된 함수를 콜백 함수라 한다.

 

 

setTimeout() 함수를 사용해 콜백 함수 사용의 예시를 보며 그 차이를 더 이해하기 쉽게 파악하고자 한다.

 

< 콜백 함수를 사용하지 않고 setTimeout() 함수를 사용한 경우 >

function first(){
  setTimeout(function(){
    console.log("first");
  }, 3000);
  second();
}

function second(){
  console.log("second");
}

first();

실행 결과

위 코드는 콜백 함수를 사용하지 않고 setTimeout() 함수를 사용하여 first와 second를 출력해보는 것이다.

실행 결과를 보면 first가 먼저 출력되는 것이 아닌 second가 먼저 출력되는 결과를 확인할 수 있다.

이와 같은 결과는 setTimeout()으로 인해 console.log("first")는 3초간 대기가 되는 상태이고, 대기 중 second() 함수가 실행되어 console.log("second")가 실행돼 second가 출력되고 first가 나중에 출력되는 것이다.

 

하지만 우리는 first가 먼저 출력되길 원한다.

이때 콜백 함수를 사용하여 아래 예시와 같이 해결할 수 있다.

 

 

< 콜백 함수를 사용하고 setTimeout() 함수를 사용한 경우 >

function first(callback){
  setTimeout(function(){
    console.log("first");
    callback();
  }, 3000);
}

function second(){
  console.log("second");
}

first(function(){
  second();
});

 

위와 같이 코드를 작성하면 first 함수가 실행되어 "first"가 먼저 찍히고, 매개 변수로 받은 콜백 함수가 다음으로 실행되어 "second"가 출력된다.

 

 

콜백 함수의 문제점

function print(callback){
  setTimeout(function() {
    callback();
  }, 3000);
}

print(function(){
  console.log("first");
  print(function() {
    console.log("second");
    print(function() {
      console.log("third");
    });
  });
});

콜백 지옥 예시 - 3초후 "first" 출력, 3초후 "second" 출력, 3초후 "third" 출력

 

콜백 함수는 비동기 작업을 순차적으로 실행하기 위해서는 유용하지만, 중첩이 반복되는 상황에서는 또 다른 문제를 발생시킨다. 이는 콜백 지옥이라고도 불린다.

콜백 함수 안에 콜백 함수를 계속 호출하는 상황이 발생하면, 즉 콜백 함수가 중첩되어 계속 사용되다 보면 가독성과 유지 보수성을 떨어트리게 된다. 콜백 지옥에 빠트릴 수 있는 단점을 보완하기 위해 promise 객체를 콜백 함수를 대체해서 사용하곤 한다.

 

다음 게시물에서는 promise에 대해 자세히 알아보겠다.

반응형