콜백(callback) 함수
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() {…}"이 있음
// loadScript 아래의 코드는 스크립트 로딩이 끝날 때까지 기다리지 X
newFunction(); // 함수가 존재하지 않는다는 에러가 발생
위 코드에서 스크립트 로딩이 끝나자마자 이 스크립트를 사용해 무언가를 해야만 한다고 가정을 하고 loadScript(...)를 호출하자마자 내부 함수를 호출하면 원하는 대로 작동하지 않는데 이것이 비동기 동작이다.
이러한 문제를 해결하기 위해 loadScript의 두 번째 인수로 스크립트 로딩이 끝난 후 실행될 함수인 콜백(callback) 함수를 추가하면,
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
// 추가할 스크립트 태그의 load 이벤트 설정
// https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
script.onload = () => callback(script);
document.head.append(script);
}
loadScript('/my/script.js', function() {
// 콜백 함수는 스크립트 로드가 끝나면 실행됩니다.
newFunction(); // 이제 함수 호출이 제대로 동작합니다.
});
두 번째 인수로 전달된 함수(보통 익명 함수)는 원하는 동작이 완료되었을 때 실행된다.
이러한 방식을 콜백 기반 비동기 프로그래밍이라고 한다.
loadScript('/my/script.js', function(script) {
loadScript('/my/script2.js', function(script) {
loadScript('/my/script3.js', function(script) {
// 세 개의 스크립트 로딩이 끝난 후 실행됨
});
});
});
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(null, script);
// 에러 처리를 위한 리스너 등록
script.onerror = () => callback(new Error(`${src}를 불러오는 도중에 에러가 발생했습니다.`));
document.head.append(script);
}
loadScript('/my/script.js', function(error, script) {
if (error) {
// 에러 처리
} else {
// 스크립트 로딩이 성공적으로 끝남
}
});
이러한 콜백 지옥 문제를 해결하기 위해 프라미스를 이용한다.