이전 블로그에서 비동기 처리는 Web API를 통해 callback queue에 넣어진callback function을 통해서 처리함을 알 수 있다. 결국 callback function을 이용하여 비동기를 처리할 수 밖에 없다는 소리이다. 그럼 callback function을 이용하여 비동기를 처리하는 예제를 살펴보자. 이번 예제에서는 대표적인 Web API인 setTimeout
을 이용할 것이다.
🤔 callback function(콜백 함수)란?
콜백이란 이름은 친구와의 대화에서도 들어볼 수 있다.
친구: "야 너 왜 콜백 안해???"
나: "아 전화했었어 미안..."위의 대화를 보면 콜백이란 다시 전화를 하는 행동
답신전화
를 뜻함을 알 수 있다.
위처럼 callback이란 이름이 붙은 이유는 어떤 작업이 완료되었을 때 호출하는 경우가 답신 전화를 뜻하는 callback과 같아 붙여졌다고 한다.콜백이란 함수가 함수의 인자로서 전달되는 함수를 뜻하며 나중에 어떤 event가 발생했을 시 즉,
특정한 시점에서 함수를 실행시키고 싶을 때 callback function을 사용
한다.
부가적으로 더 내용을 추가하자면 함수를 매개변수로서 받는 함수 또는 함수를 반환하는 함수를고차함수(higher-order function)
라 한다.“higher-order function” is a function that accepts functions as parameters and/or returns a function.
파라미터로 함수를 받는 고차함수
함수를 반환하는 고차함수
setTimeout
을 이용하여 1초마다 순차적으로 배경색이 바뀌이 빨강 -> 주황 -> 노랑
으로 바뀌는 것을 목표로 하자.
무지성 코드
setTimeout(() => (document.body.style.backgroundColor = "red"), 1000);
setTimeout(() => (document.body.style.backgroundColor = "orange"), 1000);
setTimeout(() => (document.body.style.backgroundColor = "yellow"), 1000);
하지만, 결과에서 알 수 있듯이 노랑색 배경만이 나옴을 알 수 있다. 이는 순차적으로 거의 동시에 callback 함수의 호출이 발생했기 때문이다. 내가 원하는 것은 순차적으로 배경화면을 바꾸는 것이다.
이를 위해서는 배경화면이 빨간색으로 변경됨을 보장 시 배경화면을 주황색으로 변경
되어야 한다. 좀 풀어서 쓰자면, 배경색이 빨간색으로 바뀌고 나서 주황색으로 바뀌는 코드를 실행해야함
을 뜻한다. 이는 빨간색으로 배경화면을 변경하는 callback function이 호출될 때 딱 그 시점에서 배경화면을 주황색으로 바꾸는 setTimeout API가 실행되어야 한다.
callback안에서 setTimeout을 호출
setTimeout(() => {
document.body.style.backgroundColor = "red"
setTimeout(() => {
document.body.style.backgroundColor = "orange"
setTimeout(() => {
document.body.style.backgroundColor = "yellow"
}, 1000);
}, 1000);
}, 1000);
와아아아아아아🥳🥳🥳 비동기 처리 그냥 callback function을 적절하게 써주면 쉽게 처리되네!!!!라고 생각하면 오산이다..... 만약에 callback function을 아래와 같이 많이 써야 된다고 가정해보자.
비동기 처리를 callback function으로만 작성할 때
setTimeout(() => {
document.body.style.backgroundColor = "red";
setTimeout(() => {
document.body.style.backgroundColor = "orange";
setTimeout(() => {
document.body.style.backgroundColor = "yellow";
setTimeout(() => {
document.body.style.backgroundColor = "green";
setTimeout(() => {
document.body.style.backgroundColor = "blue";
setTimeout(() => {
document.body.style.backgroundColor = "navy";
setTimeout(() => {
document.body.style.backgroundColor = "purple";
// lots of callback function calls
// ...
// ...
}, 1000);
}, 1000);
}, 1000);
}, 1000);
}, 1000);
}, 1000);
}, 1000);
위 코드만 봐도 메스껍다...... 사실상 동일한 setTimeout을 호출하는 것으로 어찌어찌 하라해서 하면 하겠는데 db에서 데이터를 받고 파싱하고 fetch를 이용하여 API 받아오고 등등 모든 비동기 작업을 위와 같이 하면 개발자하고 싶지 않을 것 같다....🥲🥲🥲
callback hell에 대한 코드에 대한 느낌을 간단하게 코드로 적으면 아래 코드를 다 펼친 느낌같다.
while(처리할 비동기가 없을 때 까지){
비동기 처리 -> 콜백함수 호출
}
위와 같이 많은 비동기 처리를 callback function안에 다 때려박아 생기는 문제를
callback hell(콜백 지옥)
이라고 한다.
나는 콜백지옥을 이용하여 비동기를 처리할 수는 있기 때문에 콜백이 하나의 수단이 될 수는 있을 것 같지만... 가장 큰 문제점은 가독성이라 판단한다.
promise와 async & await를 하기까지 필요한 지식들을 정리하면서 많은 생각을 하게 된다. 결국 비동기를 내가 원하는 동기처리 즉, 원하는 순서대로 바꾸어 원하는 작업을 하기 위해 사용하는 느낌이 든다. 그리고 지금 이 시점 마쳐 섹션을 쓰면서 callback hell은 가독성의 문제도 있지만, 비동기를 처리하는 코드 안에서 동기 코드의 순서를 맞추기도 상당히 어려워 순서조작에도 문제가 생길 것 같다.
하지만, 이를 해결할 수 있는 Promise가 있다. 이는 다음 블로그에 정리할 예정이다.
definition callback function & higher order function
colt steele course