promise vs callback

진성·2022년 5월 30일
0

자바스크립트

목록 보기
23/23

callback

callback 함수란 함수의 인자로

const foo = (callback) => {
  console.log(`hello ${callback()}`)
}

foo(function() { return "world" }) // hello wordl

위와 같이 함수의 인자로 넘겨주는 함수를 콜백 함수라고 한다.
map과 같은 메서드 형태에서 주로 보인다.
이는 주로 비동기 처리에서 동기 처리를 할 때 callback 패턴을 사용한다.

function foo () {
  const apiRequest = new XMLHttpRequest()
  apiRequest.open("get", "rest-qpi 경로")
  apiRequest.send()
  apiRequest.addEventListener("load", (res) => {
    console.log(res)
  })
}

예를 들어 위와 같이 외부 api에 데이터를 요청하고 그를 받아와야 할 때 사용한다.
하지만 이때 문제가 생기는 것이 있는데 만약 응답 받은 데이터를 이용해 또 다른 데이터를 조회해야 한다면 콜백 함수의 중첩이 많아지게 된다.

function foo () {
  const apiRequest1 = new XMLHttpRequest()
  apiRequest1.open("get", "rest-qpi 경로")
  apiRequest1.send()
  apiRequest1.addEventListener("load", (res) => {
    const result1 = res.target.data
    
    const apiRequest2 = new XMLHttpRequest()
    apiRequest2.open("get", "rest-qpi 경로")
    apiRequest2.send()
    apiRequest2.addEventListener("load", (res) => {
      const result2 = res.target.response
      
      const apiRequest3 = new XMLHttpRequest()
      apiRequest3.open("get", "rest-qpi 경로")
      apiRequest3.send()
      apiRequest3.addEventListener("load", (res) => {
        console.log(res) // 최종 결과
      })
    })
  })
}

요청한 데이터를 이용해 조회를 해야한다면 위와 같은 형태가 나오게 되고 더욱 많이 가지고 와야 한다면 이는 가독성이 좋지 않아 진다.
이러한 것을 흔히 콜백 지옥이라고 부른다.

그래서 이를 해결하기 위해서 나온 것이 Promise이다.

Promise

프로미스(Promise)란 자바스크립트의 비동기 처리를 위한 클래스이다.
자바스크립트 기본적으로 동기 처리이기 때문에 데이터를 응답 받는것과 같은 것들은 받아오는 시간이 있기에 데이터를 제대로 받을 수가 없다.
그래서 이러한 문제 때문에 비동기 처리를 해야 하는데, 이 때 사용하는 것이 프로미스이다.
프로미스는 클래스이며 instance 객체를 만들어서 매개변수로 resolve, reject, callback 함수들을 사용하여 조건에 따라 동기 처리를 한다.

new Promise((resolve, reject) => {
  // 외부 요청 코드
  
  // 성공
  resolve("요청 데이터 결과")
  
  // 실패
  reject("에러발생")
}).then((res) => {
  console.log(res) // "요청 데이터 결과"
}).catch((err) => {
  console.log(err) // "에러 발생"
})

위와 같이 resolve는 데이터 요청이 성공했을때 데이터를 받아오고 그 결과를 then에서 사용할 수 있다.
reject는 에러가 발생했을때 catch 리턴하게 된다.
하지만 이 또한 성공하면 또 콜백 지옥과 다를게 없어 보인다.
그래서 이를 axios를 이용하면 조금 더 가독성 좋게 사용할 수 있게 된다.

axios

axios는 기존에 프로미스로 만들어졌다.

axios.get("api 요청 경로")
  .then((res) => {
  return axios.get(`api 요청 경로${res}`)
}).then((res) => {
  return axios.get(`api 요청 경로${res}`)
}).then((res) => {
  console.log(res) // 최종 결과
})

axios에서 리턴을 하게 되면 프로미스를 리턴하는것과 같아지고 그 결과를 아래엔 then에서 받아서 사용할 수 있게 된다.
이처럼 아래로 체이닝 된다해서 프로미스 체인이라고 부른다.

이때 조금 주의해야 하는 것이 있다.

const foo = () => {
  console.log("1번")
  axios.get("api 요청 경로")
   .then((res) => {
     console.log("2번")
   	 return axios.get(`api 요청 경로${res}`)
 }).then((res) => {
     console.log("3번")
     return axios.get(`api 요청 경로${res}`)
 }).then((res) => {
     console.log("4번")
     console.log(res) // 최종 결과
 })
  console.log("5번")
}

// 결과 => 1번, 5번, 2번, 3번, 4번

위 코드를 확인해보면 내가 생각했던거랑은 조금 다르게 실행이 된다.
이는 태스크 큐에 의해서 이렇게 실행이 되는 것이다.
프로미스나 setTimeout과 같은 시간 관련된 기능들은 큐라는 곳에 들어가게 되고 이는 콜스택에 쌓여있는 함수가 모두 빠진후에 실행이 되기에 이러한 결과가 나오는 것이다.
큐과 콜스택은 나중에 조금 더 자세히 다루어 볼것이다.

참고 : callback, Promise, async-await

profile
풀스택 진행중...

0개의 댓글