콜백 헬이라는 말 들어보셨나요? 보통 promise, async-await 문법을 배울 때 흔히 접할 수 있는 말입니다. 우리를 콜백 헬에서 구해주는 문법으로 promise-then이 나왔다고 말이죠. 이번 포스트에서는 자바스크립트의 악명높은 콜백에 대해서 알아보겠습니다. 왜 콜백이 존재하고, 왜 사용하고, 뭐가 문제인지 함께 파헤쳐 보겠습니다.
먼저 콜백함수의 정의부터 시작해봅시다.
초급 정의: 함수 안에 파라미터로 들어가는 함수
중급 원리
function first(파라미터){
파라미터();
}
function second(){
}
first(second());
결국 콜백함수는 어떤 작업을 순차적으로 실행하고 싶어서 쓰는것입니다. 그러면 first함수 다음에 second함수 실행하고 싶으면 어떻게 코드를 짜야할까요?
그냥 다음과 같이 한 번 짜봅시다.
function first(파라미터){
console.log(1);
파라미터();
}
function second(){
console.log(2);
}
first(second); //first실행해주세요, 파라미터 자리엔 second넘겨주세요
1 2
아니 근데, 잘 생각해보니 굳이 이렇게 해야할까요?
그냥 이렇게 하면 안될까요?
first();
second();
맞아요. 이렇게만 보면 콜백이 쓸데가 없어보입니다. 그런데 사용할 때가 가끔 있습니다. 예를 들어 협업을 할 때 first함수를 만들었다고 생각해보겠습니다. 다른사람들이 내가 만든 first함수를 즐겨 쓰고 있습니다. 그런데 다음과 같은 요구사항이 생깁니다.
🧑팀원1: 나는 first 함수 실행 다음에 console.log(1) 실행하고 싶어요!
🧔팀원2: 나는 first 함수 실행 다음에 console.log(4) 실행하고 싶어요!
이러한 요구들이 계속 생겨난다면, 일단은 이렇게 할 것 같습니다.
그냥 first() 호출하고 그 밑에다가 원하는거 쓰면 됩니다~
first()
console.log(1) //아니면 다른 작업 아무거나요~
그런데 뭔가 불안하지 않으세요? first()가 실행되고 나서 무조건 순차적으로 그 다음줄이 실행되는 그 순서가 보장될까요?
first()함수가 만약 비동기 함수라면 이 순서는 지켜지지 않습니다.
이럴 때 first함수의 파라미터 자리에 콜백함수를 추가하여 first() 다음에 실행할 코드를 파라미터로 받는다면 원하는 순서를 보장할 수 있습니다.
function first(파라미터){
....//first 함수 원래 내용
파라미터();
}
first(function(){console.log(1)})
결론적으로 남이 쓸 코드 자리를 남겨놓을 때 가끔 콜백함수를 사용합니다.
그런데 콜백함수를 너무 많이쓰면 단점이 보일 때가 있습니다. 콜백함수가 자주 쓰이는 부분인 DB에서 데이터를 빼오는 경우를 생각해보죠. 다음과 같은 흐름을 원한다고 합시다.
DB에서 데이터 뽑고 싶네... 근데 A를 뽑고 그 다음에 B뽑고, 그다음에 C 뽑고 싶음..
이를 달성하기 위해 콜백함수를 사용하면 다음과 같은 그림이 됩니다.
db.collection('post').findOne(A, function(){
db.collection('post').findOne(B, function(){
db.collection('post').findOne(C, function(){
...
})
})
})
코드가 상당히 복잡하고 우측으로 길어지는 것을 볼 수 있습니다. 그럼 어떻게 해야 할까요?
어쩔수 없습니다. 여러분이 선택한 자바스크립트고, 악으로 깡으로 버텨야 합니다.
그런데 이게 정말 싫으면 Promise나 async, await키워드를 써서 순차적 실행에 대한 처리를 대체할 수도 있습니다.