async-2(callback & promise & callback hell)

GI JUNG·2023년 1월 23일
4

javascript

목록 보기
8/12
post-thumbnail

이전 블로그에서 비동기 처리는 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.

파라미터로 함수를 받는 고차함수

함수를 반환하는 고차함수

🍀 aysnc & callback

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 hell

와아아아아아아🥳🥳🥳 비동기 처리 그냥 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

profile
step by step

0개의 댓글