[Node.js] callback이란?

Joney의 SW 공부 블로그·2023년 6월 1일
0

Node.js

목록 보기
1/3

비동기 처리

  • 특정 코드의 연산이 끝날 때까지 기다리지 않고 다음 코드의 작업을 실행하는 처리

비동기 처리 예시

// ms(밀리세컨드)동안 대기 후, str 출력하는 함수 
function process(str, ms){
    setTimeout(() => {
      console.log(str);
    }, ms);
  };

console.log(1);
process('테스트!', 1000);
console.log(2);

위 코드를 실행하게 되면 아래와 같은 결과가 되는 것을 확인할 수 있다.

1
2
테스트!

2를 출력하는 코드는 process함수보다 뒤에 있는데 먼저 실행되고 있다.
Javascript는 비동기 처리를 하는 특성을 가지고 있기 때문에 process함수의 처리가 끝나기를 기다리지 않고 다음 코드가 실행되고 있다.



callback

이런 비동기 처리에 문제가 발생하는 경우가 있다.
예를 들어, 아래와 같이 데이터베이스에서 데이터를 조회해서 표시하는 코드가 있다고 할 때, 비동기 처리로 인해 undefined가 출력되어 데이터를 알 수 없게 된다.

function get_data(){
    // 데이터베이스에서 데이터를 가져오는 코드
  return data
};

const data = get_data();
console.log(data);

이런 문제를 없애기 위해 callback 함수를 사용해서 동기로 처리할 수 있다.


위의 비동기 처리 예시 코드를 사용해 보자.

function process(str, ms, callback){
    setTimeout(() => {
      console.log(str);
      callback()
    }, ms);
  };

console.log(1)
process('테스트!', 1000, function(){
    console.log(2)
});

위 코드를 실행해보면 아래와 같이, 순서에 맞게 실행되는 것을 확인할 수 있다.

1
테스트!
2



callback 속의 callback

만약 여러개의 프로세스가 있고 각 프로세스가 순차적으로 처리되어야 한다면, 아래와 같이 코드를 만들면 안된다는 것을 위에서 알 수 있다.

const process = (str, wait) => {
    setTimeout(() => {
      console.log(str);
    }, wait);
  };

console.log('start');
process('프로세스1', 1000); // 1초 걸리는 프로세스
process('프로세스2', 500); // 0.5초 걸리는 프로세스
process('프로세스3', 100); // 0.1초 걸리는 프로세스
console.log('end');
start
end
프로세스3
프로세스2
프로세스1

각 프로세스를 callbcak 함수로 묶어서 처리하면 순차적으로 처리할 수 있다.

function process(str, ms, callback){
  setTimeout(() => {
    console.log(str);
    callback()
  }, ms);
};
  

console.log('start');
process('프로세스1', 1000, () => {
  process('프로세스2', 500, () => {
    process('프로세스3', 100, () => {
        console.log('end');
    });
    });
});
start
프로세스1
프로세스2
프로세스3
end

이와 같이 callback 속에 callback을 넣어서 각 프로세스가 끝나면 다음 프로세스를 진행하도록 만들 수 있다.


하지만, 프로세스가 많아지면 코드의 depth가 깊어지게 되고, "callback 지옥"이라고 불리는 가독성이 좋지 않는 코드가 만들어지게 된다.

이런 코드를 막기 위해서 promise나 async/await을 사용한다.

여기서는 promise나 async/await을 사용하지 않고 코드 패턴으로만 callback 지옥을 탈출하려면 아래와 같이 callback 함수를 나눠서 정의하면 된다.

function process(str, ms, callback){
  setTimeout(() => {
    console.log(str);
    callback()
  }, ms);
};

function process1Done() {
    process('프로세스2', 500, process2Done);
}

function process2Done() {
    process('프로세스3', 100,  () => {
        console.log('end');
    });
}
  
console.log('start');
process('프로세스1', 1000, process1Done);



error handling

callback을 사용해서 코드 실행에서 에러가 발생했을 경우의 처리를 정의할 수 있다.
보통 callback의 첫번째 인수는 에러를 위해 사용된다.

loadScript('/my/script.js', function(error, script) {
  if (error) {
    // 에러가 발생한 경우의 처리
  } else {
    // 코드 처리가 성공적으로 된 경우 처리
  }
});
profile
SW 지식 노트 블로그

0개의 댓글