본문으로 바로가기

⚡ 콜백함수

 

콜백 함수는 다른 코드의 인자로 넘겨주는 함수입니다. 콜백 함수를 넘겨받은 코드는 적절한 시점에 콜백 함수를 실행합니다. 굳이 콜백 함수라고 말해서 어렵게 느껴질 수도 있지만 그냥 특정한 시점이나 이벤트에 반응해서 실행하는 함수를 말합니다.

콜백이라고 이름 붙인 이유는 callback 즉, 특정 이벤트나 시점에 자신을 불러달라고 하는 데에서 왔습니다. 그러니까 어렵게 생각하지 맙시다. 콜백 함수는 그냥 함수입니다.

setTimeout(() => console.log("test"), 3000))
el.addEventListener("click", () => setCount(count + 1))

 

콜백 함수가 중요한 이유는 위와 같이 setTimeout, setInterval과 같이 대놓고 콜백 함수가 보이는 경우보다 자연스레 메서드의 인자에 콜백 함수가 들어간 경우가 많기 때문입니다.

 

배열에서 자주 쓰는 메서드인 map에 대한 MDN의 설명만 보아도 그렇습니다.

 

let new_array = arr.map(function callback(currentValue[, index]) {
  // return element for new_array
}[, thisArg])

map 메서드는 배열의 각 요소들을 하나씩 꺼내어 콜백함수를 반복 호출하고 콜백함수 실행 결과값을 모아 새로운 배열을 만듭니다.

// 예시 1
const array = [1, 3, 5].map((e, i) => {
  console.log(e, i);
  return e + 5;
});

console.log(array);
// [6, 8, 10]

// 예시 2
const array = [5, 10, 15];

const newArray = array.map((e) => e + 5);
console.log(newArray);
// [10, 15, 20]

 

 

⚡ 콜백지옥과 비동기제어

 

* 비동기 : 즉시 처리가 불가능한, 대기하고 요청하는 등의 코드는 비동기적인 코드입니다.

 

콜백 지옥이라는 것은 비동기처리를 위해 콜백 안에 콜백 안에 콜백.... 이 이어지는 코드입니다. 위의 코드의 경우 링크를 로드하는 비동기 처리를 콜백 안에 콜백 안에 콜백...으로 처리하고 있습니다. 당연히 코드 유지 보수하기도 어렵도 처리하기도 힘듭니다. 

 

이런 콜백 지옥을 해결하기 위해서 Promise, Generator, async/await 등의 해결 방법이 있습니다. 콜백 지옥에서 시작해서 코드를 점차 고쳐나가는 방식으로 살펴봅시다.

 

 

콜백지옥 예시

 

0.5초마다 conffieList에 추가하도록 코드를 짰습니다. 3개만 중첩된 상태지만 벌써부터 별로 보기에 좋지 않습니다.

setTimeout(
  (name) => {
    let coffeList = name;
    console.log(coffeList);
    setTimeout(
      (name) => {
        coffeList += `, ${name}`;
        console.log(coffeList);
        setTimeout(
          (name) => {
            coffeList += `, ${name}`;
            console.log(coffeList);
          },
          500,
          "에스프레소"
        );
      },
      500,
      "카페라떼"
    );
  },
  500,
  "아메리카노"
);

 

Promise 적용

new Promise((resolve) => {
  setTimeout(() => {
    const name = "에스프레소";
    console.log(name);
    resolve(name);
  }, 500);
}).then((preName) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      const name = preName + `, 아메리카노`;
      console.log(name);
      resolve(name);
    }, 500);
  });
});

 

Promise + async/await

const addCoffee = (name) => {
  return new Promise((resolve) => {
    setTimeout(() => resolve(name), 500);
  });
};

const coffeMaker = async () => {
  let coffeList = "";
  const addNewCoffee = async (name) => {
    coffeList += (coffeList ? "," : "") + (await addCoffee(name));
  };
  await addNewCoffee("에스프레소");
  console.log(coffeList);
  await addNewCoffee("아메리카노");
  console.log(coffeList);
  await addNewCoffee("카페라떼");
  console.log(coffeList);
};

coffeMaker();

darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체