[javascript] Callback

Yuni·2022년 7월 27일
0

코드스테이츠

목록 보기
21/39
post-thumbnail

Callback

콜백 함수는 다른 함수의 전달인자로 넘겨주는 함수이며 나중에 호출되는 함수를 의미한다.

아래 코드처럼 인수로 전달된 함수(콜백 함수)는 원하는 동작이 완료되었을 때 실행된다. 이런 방식을 콜백 기반 비동기 프로그래밍이라고 한다.

function loadScript(src, callback) {
  let script = document.createElement('script');
  script.src = src;
  script.onload = () => callback(script);
  document.head.append(script);
}

loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js', script => {
  alert(`${script.src}가 로드되었습니다.`);
  alert( _ ); // 스크립트에 정의된 함수
});

💡 다른 예시

// callback in action : 반복 실행하는 함수(iterator)
[1,2,3].map(function(el, idx){
	return el * el;
})
// callback in action : 이벤트에 따른 함수(event handler)
document.querySelector("#btn").addEventListner("click", function(e){
	console.log("click!");
})

🚨 주의
호출된 함수를 연결하는 것이 아니라 함수 자체를 연결한다.

// ⭕
document.querySelector("#btn").onclick = handleClick;
document.querySelector("#btn").onclick = function(){ handleClick(); }
document.querySelector("#btn").onclick = handleClick.bind();
// ❌
document.querySelector("#btn").onclick = handleClick();

에러 핸들링

아래 코드처럼 에러를 처리하는 방식을 오류 우선 콜백(error-first callback)이라고 한다.

오류 우선 콜백의 첫번째 인자를 이용해 에러가 발생했을 때 callback(err)을 호출한다. 두번째 인자를 이용해 원하는 동작이 성공한 경우에 callback(null, result)를 호출한다.

loadScript('/my/script.js', function(error, script) {
  if (error) {
    // 에러 처리
  } else {
    // 스크립트 로딩이 성공적으로 끝남
  }
});

Callback Hell

콜백 기반의 비동기 처리는 비동기에서 순서를 제어할 수 있지만 꼬리에 꼬리를 무는 비동기 동작이 많아지면 아래 코드처럼 콜백 지옥에 빠지게 된다.

loadScript('1.js', function(error, script) {

  if (error) {
    handleError(error);
  } else {
    // ...
    loadScript('2.js', function(error, script) {
      if (error) {
        handleError(error);
      } else {
        // ...
        loadScript('3.js', function(error, script) {
          if (error) {
            handleError(error);
          } else {
            // 모든 스크립트가 로딩된 후 실행 흐름이 이어진다.
          }
        });

      }
    })
  }
});

위의 콜백 지옥은 아래 코드처럼 각 동작을 독립적인 함수로 만들면 완화할 수 있다. 그러나 코드의 가독성이 떨어지고 재사용이 불가능하다.

loadScript('1.js', step1);

function step1(error, script) {
  if (error) {
    handleError(error);
  } else {
    // ...
    loadScript('2.js', step2);
  }
}

function step2(error, script) {
  if (error) {
    handleError(error);
  } else {
    // ...
    loadScript('3.js', step3);
  }
}

function step3(error, script) {
  if (error) {
    handleError(error);
  } else {
    // 모든 스크립트가 로딩되면 다른 동작을 수행한다.
  }
};

참고

Javascript.info 콜백

profile
배운 것을 기억하기 위해 기록합니다 😎

0개의 댓글