본문 바로가기

JavaScript

비동기함수의 순서를 제어하는 방법 1. Callback함수

# 콜백함수란?

2023.12.23 - [JavaScript] - callback함수란?

 

callback함수란?

# 함수란? - 어떤 특정한 일을 하는 코드의 묶음 - 다양하고 의미있는 일을 하기 위해 매개변수(인자)를 전달받을 수 있다. - 여러 종류의 인자를 전달받을 수 있다. ex: 숫자, 문자열, 객체 등 - 함

lion284.tistory.com

 

비동기 방식에서는 각각의 처리 로직이 '병렬'로 수행되므로, 이 처리로직이 언제 시작되고 언제 종료되는지 알 수 없다.

하지만, 순차처리를 하고싶은 경우가 있을 수 있다.

 

 

콜백함수는 원하는 시점에 호출을 할 수 있으므로, 비동기 처리가 완료되면 호출되도록 할 수 있다.

그래서 콜백함수를 중첩 사용하여 순차처리를 할 수 있다.

즉, 중첩된 콜백함수를 이용하여 순서가 보장되게끔 한다.

const printString = (string) => {
   setTimeout(() => {
      console.log(string)}, Math.floor(Math.random() * 100) + 1)
};
// 인자가 전달되면 두번째 인자인 'Math.floor(Math.random() * 100) + 1'의 시간 후,
// () => {console.log(string)}함수가 실행된다.
//하지만 Math.random로 인해 timeout시간을 아무도 알 수 없다. 완전 비동기적!

const printAll = () => {
 printString("A");
 printString("B");
 printString("C");
};

printAll();

 

위 함수를 printAll()로 호출해보면 과연 "A B C" 순서대로 찍힐까?
→ NO!

setTimeout함수에서 타임아웃시간을 random하게 줬기때문에, printAll함수를 호출할때마다 CAB, CBA, ABC 등 계속 바뀐다.

즉, 순차적으로 ABC를 제어할 수 없다.

 

하지만! 나는 Callback함수를 이용하여 순서를 제어하고 싶다!!

 

 

# callback함수를 이용하여 비동기 순서 제어

const printString = (string, callback) => {
  setTimeout(() => { 
     console.log(string);
     callback(); //인자로 callback을 추가로 받고 setTimeout함수에 callback함수 추가
    }, Math.floor(Math.random() * 100) + 1)
};

const printAll = () => {
 printString("A", () => { //console.log("A") 실행
   printString("B", () => { // console.log("B") 실행
    printString("C", () => {}) //console.log("C") 실행
    })
  })
}

printAll();

 

printAll함수를 호출을 수십번 해도 똑같이 "ABC" 순으로 나온다.

 

 

# callback함수의 한계

하지만, 콜백함수도 한계가 있으니...

그건 바로 콜백지옥! callback HELL!!
콜백에 콜백에 콜백에 콜백이 계속 이어지면

  1. 가독성이 떨어진다.
  2. 디버깅할때 굉장히 힘들다
  3. 유지보수 어렵다.