[TIL] 자바스크립트 공부 10일차

정인교·2021년 6월 1일
0

TIL(Today I Learned)

목록 보기
9/67
post-thumbnail

콜백 기초

자바스크립트에서 여러 함수들을 사용하면 비동기 동작을 스케줄링할 수 있습니다. 즉, 원하는 때에 동작을 시작하게 할 수 있죠.
그리고 스케줄링에서 가장 대표적인 함수가 setTimeout인데,
실무에선 더 많은 비동기 동작 함수가 있는데, loadScript
예를 들어보겠습니다.

function loadScript(src) {
  // <script> 태그를 만들고 페이지에 태그를 추가합니다.
  // 태그가 페이지에 추가되면 src에 있는 스크립트를 로딩하고 실행합니다.
  let script = document.createElement('script');
  script.src = src;
  document.head.append(script);
}

이 스크립트는 비동기적으로 실행됩니다. 왜냐하면 시작되더라도 실행은 함수가 끝난 후에 되기 때문인데요.
이때문에 발생한 에러 중 하나는

loadScript('/my/script.js');
// script.js엔 "function newFunction() {…}"이 있습니다.

newFunction(); 
// 함수가 존재하지 않는다는 에러가 발생합니다!

이런 에러 입니다. 함수를 긁어오는 동안 함수를 찾으니 함수는 없다고 인식되고
함수는 써야하는데 말이죠.

이럴 경우, 콜백 함수를 추가한다면 해결할 수 있습니다.

function loadScript(src, callback) {
  let script = document.createElement('script');
  script.src = src;

  script.onload = () => callback(script);

  document.head.append(script);
}

콜백 함수는 나중에 호출할 함수를 의미하고, 위처럼 사용하면 에러가 발생하지 않습니다.
이런 방식으로 콜백 기반 비동기 프로그래밍이라고 하는데,
뭔가를 비동기적으로 수행하는 함수는 함수 내 동작이 모두 처리되어야하는 함수가 들어갈 콜백을 인수로 제공해야합니다.
loadScript에서 콜백 제공하는 방식이 일반적인 접근법입니다.

콜백 속 콜백

아까 사용했던 loadScript에서, 스크립트 두 개를 순차적으로 불러오려면
콜백 함수 안에서 두 번째 loadScript를 호출해야합니다.

loadScript('/my/script.js', function(script) {

  alert(`${script.src}을 로딩했습니다. 이젠, 다음 스크립트를 로딩합시다.`);

  loadScript('/my/script2.js', function(script) {
    alert(`두 번째 스크립트를 성공적으로 로딩했습니다.`);
  });

});

이런 코드에 에러 핸들링까지한다면,

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 {
            // 모든 스크립트가 로딩된 후, 실행 흐름이 이어집니다. (*)
          }
        });

      }
    })
  }
});

보기 흉측한 코드가되고 이런 중첩코드는 콜백 지옥이라 불립니다.
비동기 동작 하나당 더 커진다면 이런 문제는 더 커집니다.
이런 코딩 방식보단, 각 동작을 함수로 만드는 것이 훨씬 좋습니다.
함수화 시키는 것 말고 프로미스라는 개념도 있습니다!

profile
백엔드 개발자 정인교입니다!

0개의 댓글