[Udemy] 콜백 지옥(Callback Hell)

OROSY·2021년 5월 1일
0

TIL

목록 보기
4/18
post-thumbnail

콜백 지옥(Callback Hell)

실제로 콜백 지옥(Callback Hell)은 매우 빈번하게 발생하게 됩니다. 아래의 예시들을 통해 알아봅시다.

1. 코드 예시(1)

setTimeout(() => {
  document.body.style.backgroundColor = 'red'
}, 1000)

setTimeout(() => {
  document.body.style.backgroundColor = 'orange'
}, 2000)

setTimeout(() => {
  document.body.style.backgroundColor = 'yellow'
}, 3000)

위와 같이 setTimeout 함수를 통해 1초마다 배경색이 변하는 코드를 작성하였습니다. 그러나 이 코드는 매번 시간을 계산해야한다는 단점이 있습니다. 이를 개선하기 위해 nesting을 해보도록 합시다.

2. 코드 예시(2)

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'
            }, 1000)
          }, 1000)
        }, 1000)
      }, 1000)
    }, 1000)
  }, 1000)
}, 1000)

이번엔 함수의 nesting을 통해서 직접 시간을 계산하지 않아도 되는 코드를 작성하였습니다. 하지만 여기서의 문제점은 같은 함수가 너무 많이 중복이 되어있다는 점입니다. 또 이번엔 이를 해결해볼까요?

3. 코드 예시(3)

const delayedColorChange = (newColor, delay, doNext) => {
  setTimeout (() => {
    document.body.style.backgroundColor = newColor
    doNext && doNext()
  }, delay)
}

delayedColorChange('red', 1000, () => {
  delayedColorChange('orange', 1000, () => {
    delayedColorChange('yellow', 1000, () => {
      delayedColorChange('green', 1000, () => {
        delayedColorChange('blue', 1000, () => {

        })
      })
    })
  })
})

이렇게 delayedColorChange라는 함수를 정의해서 별도로 호출만 진행하면 될 수 있도록 코드를 작성하였습니다. 위의 코드보다 훨씬 간결한 것을 확인할 수 있습니다. 여기서 이 함수의 세번째의 매개변수를 보시면 doNext가 있고 그 함수 안에는 doNext()라는 본인을 호출하는 함수가 있습니다. 이것이 바로 아시다시피 재귀 함수입니다.

그러나 이또한 매우 여러번의 nesting으로 인해서 굉장히 복잡하다고 생각이 드실 겁니다. 이것이 바로 콜백 지옥(Callback Hell)입니다.

4. 코드 예시(4)

searchMoviesAPI('amadeus', () => {
  saveToMyDB(movies, () => {
    // if it works, run this
  }), () => {
    // if it doesn't work, run this
  }, () => {
    // if API is down, or requests failed
  }
})

실제로 위와 같은 코드가 매우 자주 사용됩니다. API에게 요청을 하여, 데이터를 받아오고 API 요청이 제대로 됐다면 나의 DB에 저장합니다. 그러나 이러한 일이 반드시 될 것이란 보장이 없겠죠?

API가 다운이 될 수도, 요청이 실패할 수도 그리고 내 DB에 저장하는 도중에 갑자기 오류가 발생할 수도 있습니다. 이러한 상황에서 콜백 지옥(Callback Hell)은 무수히 많이 일어나게 됩니다.

이러한 일은 JavaScript는 싱글 스레드로 작동하며, 한 번에 하나씩만 처리할 수 있는 로직으로 만들어져있기 때문입니다. 따라서 우리는 코드의 실행을 지연(delay)하기 위해 WebAPI를 통해 콜백(Callback)을 사용해야만 합니다. 그러므로 이렇게 코드가 복잡해지는 것이죠.

5. 해결책은 없는가

그러나 다행히도 이러한 콜백 지옥(Callback Hell)을 쉽게 해줄 수 있도록 최신의 JavaScript의 버전에서는 promise와 async function이라는 개념을 사용할 수 있게 되었습니다. 다음 시간부터는 이에 대해 알아보도록 합시다.

profile
Life is a matter of a direction not a speed.

0개의 댓글