콜백
- 자바스크립트 호스트 환경이 제공하는 여러 함수를 사용하면 비동기 동작을 스케줄링 할 수 있다 즉 원하는 때에 동작이 시작하도록 할 수 있다는 것이다.
- setTimeout 이 스케줄링에 사용되는 가장 대표적인 함수이다
- 실무에서 맞닥뜨리는 비동기 동작은 아주 다양하다 스크립트나 모듈을 로딩하는 것 또한 비동기 동작이다
- 위 예제는 src에 있는 스크립트를 읽어오는 loadScript(src) 함수를 만들었다.
- 위 loadScript는 <script src='...'>를 동적으로 만들고 이를 문서에 추가한다 브라우저는 자동으로 태그에 있는 스크립트를 불러오고 로딩이 완료되면 스크립트를 실행한다.
- 이때 스크립트가 비동기적으로 실행된다 로딩은 지금 당작 시작되더라도 실행은 함수가 끝난 후에야 되기 때문이다
-
- 따라서 위 예제처럼 loadScript() 아래에 있는 코드들은 스크립트 로딩이 종료되는 걸 기다리지 않기 때문에 먼저 1이 콘솔로 찍히고 그 다음 script.js에 있는 2가 콘솔로 찍힌다.
- 만약 스크립트 로딩이 끝나자마자 이 스크립트를 사용해 무언가를 사용해야만 한다고 가정해보자 스크립트 안에 다양한 함수가 정의되어 있고 우리는 이 함수를 실행하는 원하는 상황이다
- 그런에 위 예제처럼 loadScript()를 호출하자마자 내부 함수를 호출하면 에러가 발생한다.
- 이런 에러는 브라우저가 스크립트를 읽어올 수 있는 시간을 충분히 확보하지 못했기 때문에 발생한다 현재로서는 LoadScript 에서 스크립트 로딩이 완료되었는지 알 방법이 없다.
- 원하는 대로 스크립트 안의 함수나 변수를 사용하려면 스크립트 로딩이 끝났는지 여부를 알 수 있어야 한다.
- loadScript의 두번째 인수로 스크립트 호딩이 끝 난 후 실행될 함수인 콜백 함수를 추가했다 콜백함수란 나중에 호출할 함수를 의미한다.
- 새롭게 불러온 스크립트에 있는 함수를 콜백 함수 안에서 호출하면 원하는 대로 외부 스크립트 안의 함수를 사용 할 수 있다 .
콜백 속 콜백
- 스크립트가 2개 있는 경우 어떻게 하면 두 스크립트를 순차적으로 불러올 수 있는 방법은 콜백함수 안에서 또 LoadScript를 호출하는 것이다
- 이렇게 중첩 콜백을 만들면 바깥에 위치한 loadScript가 완료된 후 안쪽 loadScript가 실행된다.
- 여기서 스크립트 하나를 더 불러오고 싶다면 2번째 loadScript 콜백함수에다 또 loadScript를 추가하면 된다.
에러 헨들링
- 지금까지 예제는 스크립트 로딩이 실패하는 경우 등의 에러는 전혀 고려하지 않고 작성되었다 하지만 스크립트 로딩이 실패할 가능성은 언제나 존재한다 물론 콜백함수는 이런 에러를 핸들링 할 수 있어야 한다.
- loadScript 에 로딩 에러를 추적할 수 있게 기능을 개선했다. 이제 loadScript는 스크립트 로딩에 성공하면 callback(null, script) 를 실행하고 실패하면 callback을 실행한다
- 개선된 loadScript는 위 예제처럼 사용한다.
- 이렇게 에러를 처리하는 방식은 흔히 사용되는 패턴이다 이런 패턴을 오류 우선 콜백이라고 불린다.
- 오류 우선 콜백은 다음 관례를 따른다
1 callback의 첫번째 인수는 에러를 위해 남겨둔다 에러가 발생하면 이 인수를 이용해 callback(err) 호출된다.
2 두번째 인수는 에러가 발생하지 않았을 때를 위해 남겨둔다 원하는 동작이 성공한 경우 callback(null, result)가 호출된다
- 오류 우선 콜백 스타일을 사용하면 단일 콜백 함수에서 에러 케이스와 성공 케이스 모두 처리할 수 있다,
콜백 지옥
- 콜백 기반 비동기 처리는 언뜻 봤을 때 꽤 쓸만해 보이고 실제로도 그렇다 한 개 혹은 두개의 중접 호출이 있느 경우는 보기에도 나쁘지 않다.
- 하지만 꼬리에 꼬리를 무는 비동기 동작이 많아지면 콜백지옥이라는 중첩 패턴이 발생한다.
- 호출이 계속 중첩되면서 코드가 깊어지고 있다 따라서 이런 코딩 방식은 좋지 않다.
- 위 예제처럼 각 동작을 독립적인 함수로 만들어 문제를 완화할 수 있다.
- 각 동작을 분리해 최상위 레벨의 함수로 만들었기 때문에 깊은 중첩이 없다 그리고 콜백 기반 스타일 코드와도 동일하게 작동한다.
- 하지만 이러한 코딩 스타일도 동작상의 문제는 없지만 코드가 찢어진 종잇조각 같아 보인다는 문제가 생긴다
- 다행이도 이러한 콜백 지옥을 피할 방법은 여러개가 있다 가장 좋은 방법은 promise를 사용하는 것이
'자바스크립트' 카테고리의 다른 글
[Javascript] - Promise 체이닝 (0) | 2022.12.16 |
---|---|
[Javascript] - Promise (0) | 2022.12.07 |
[Javascript] - try & catch와 에러 핸들링 (0) | 2022.11.12 |
[Javascript] - instaceof로 클래스 확인하기 (0) | 2022.10.17 |
[Javascript] - require vs import (0) | 2022.10.08 |