Written by
Nostrss
on
on
[JS]과하면 멸망하는 콜백 함수
Callback
콜백 함수는 다른 함수에 인수로 전달된 함수이며 외부 함수 내부에서 호출되어 일종의 루틴이나 작업을 완료하는 것을 말한다.
동기식 Callback
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput(callback) {
var name = prompt('Please enter your name.');
callback(name);
}
processUserInput(greeting);
비동기식 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( _ ); // 스크립트에 정의된 함수
});
비동기식 콜백은 일반적으로 무언가를 비동기적으로 수행하는 함수는 함수 내 동작이 모두 처리된 후 실행되어야 하는 함수가 들어갈 콜백을 인수로 반드시 제공하는 식으로 이루어진다.
콜백 속 콜백
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 {
// 모든 스크립트가 로딩된 후, 실행 흐름이 이어집니다. (*)
}
});
}
})
}
});
호출이 계속 중첩되면서 코드가 점점 깊어지고.. 반복문과 조건문이 있는 코드가 들어가고..
이렇게 깊은 중첩 코드가 만들어내는 패턴은 소위 ‘콜백 지옥(callback hell)’ 이라고 부릅니다.
따라서 이런 코딩 방식은 좋지 않기 때문에 각 동작을 독립적인 함수로 만들어서 위와 같은 문제를 완화하는 것이 좋다.