[JavaScript] How to use Fetch API? Fetch API 사용하는 방법, 이유

이은진·2020년 11월 4일
0

JavaScript Study

목록 보기
4/24

XMLHttpRequest()로 데이터를 받아 온 방식에서 Fetch API를 활용하는 방식으로 변환하면서 설명한다.

1. XMLHttpRequest()와 fetch() 코드 비교분석

XMLHttpRequest() 방식으로 랜덤 글자 생성 링크에서 데이터를 받아오고, 그것을 출력하는 코드

const getPuzzle = (wordCount) => new Promise((resolve, reject) => {
    const request = new XMLHttpRequest()
    request.addEventListener('readystatechange', (e) => {
        if (e.target.readyState === 4 && e.target.status === 200) {
            const data = JSON.parse(e.target.responseText)
            resolve(data.puzzle) //(에러, 데이터)
        } else if (e.target.readyState === 4) {
            reject('An error has taken place')
        }
    })
    request.open('GET', `http://puzzle.mead.io/puzzle?wordCount=${wordCount}`)
    request.send()
})
getPuzzle('2').then((puzzle) => { 
  console.log(puzzle) 
}, (err) => {
  console.log(`Error: ${err}`)
})

fetch() 방식으로 데이터를 받아온 후 출력하는 코드

fetch('http://puzzle.mead.io/puzzle', {}).then((response) => {
  if (response.status === 200) {
    return response.json() //.json() method takes the response body and parse it as JSON
  } else {
    throw new Error('Unable to fetch puzzle') //if we manually throw error, catch() is fired
  }
}).then((data) => { //.then() is going to access to the data, and then we can do something with parced JSON, for example console.log()
  console.log(data.puzzle)
}).catch((error) => {
  console.log(error)
})
  1. Fetch API is a second way we can make http requests in newer versions of js, this new API has promises built-in, which XMLHttpRequest() doesnt support
    Fetch API는 자바스크립트의 이전 버전에서 폭넓게 쓰이던 XMLHttpRequest()의 업그레이드 버전이며, 이 자체로 프로미스 형태다. 데이터 요청할 때 쓰인다.

  2. We can access to the Fetch API by fetch() with an argument: url (, optional additional argument)
    fetch()에 인자로 원하는 데이터의 경로 url을 쓴다.

  3. Fetch returns a promise, so we can wait for this promise to resolve or reject with data we requested
    Dont have to worry about readystate, cus this promise(fetch()) is going to resolve or reject only when it's ready for us. no worry about IF it's completed, just worry about HOW it's completed(400, 500, etc)
    XMLHttpRequest()과 달리 readystate에 신경쓰지 않아도 된다. fetch는 프로미스이기 때문에 애초에 resolve된 결과만 보여주기 때문. 즉 응답이 돌아왔는지 안 돌아왔는지 여부가 중요한 게 아니라, 어떻게 돌아왔는지(에러코드 400 500대 등)만 신경쓰면 된다.

2. 만들어진 코드와 실행에 필요한 코드 분리하기

위의 fetch() 방식으로 작성한 코드를 분리해서, 앱 실행에 적합한 방식으로 다시 작성해보면

const getPuzzle = (wordCount) => {
    return fetch(`http://puzzle.mead.io/puzzle?wordCount=${wordCount}`).then((response) => {
        if (response.status === 200) {
            return response.json()
        } else {
            throw new Error('Unable to fetch puzzle')
        }
    }).then((data) => {
        return data.puzzle
    })
}
getPuzzle('2').then((puzzle) => { 
  console.log(puzzle) 
}).catch((err) => {
  console.log(`Error: ${err}`)
})
  1. Only leave last .then() and last .catch() call. we dont want fetch() thing everytime we call getPuzzle().
    마지막 .then()과 .catch() 메서드만 남기고 나머지 복잡한 코드를 분리했다. (유지보수의 용이성을 위해)

  2. We need a promise to come back cuz we're using .then() , so we can call getPuzzle('2').then() like this
    마지막 .then()을 붙이기 위해 getPuzzle()은 프로미스 형태여야 한다. 따라서 위의 복잡한 코드 부분에서 프로미스 형태인 fetch() 자체를 리턴해서 getPuzzle().then()과 같이 연결했다.

복잡한 코드는 다른 파일로 분리하고 실행에 필요한 최소한만 남기기.

const getPuzzle = (wordCount) => {
    return fetch(...)
}
getPuzzle('2').then(...)
  1. what we get back from .json() method: not javascript object, it's a promise, so we can add another promise chain .then() is going to access to the data, and then we can do something with parced JSON, for example console.log()
    .json() 메서드의 결과는 객체가 아닌 프로미스이기 때문에 .then() 메서드로 프로메스 체인을 붙여나가며 데이터에 차례로 접근할 수 있다. .then()으로 접근한 파싱된 JSON 데이터로 출력하거나 다음 작업을 수행하면 된다.

아래와 같이 response.json()으로 나온 결과에 바로 .then()을 붙여 프로미스 체인 만들면 된다.

fetch(`http://puzzle.mead.io/puzzle?wordCount=${wordCount}`).then((response) => {
        if (response.status === 200) {
            return response.json()
        } else {
            throw new Error('Unable to fetch puzzle')
        }
    }).then((data) => {
        return data.puzzle
    })
  1. We dont have to return a promise from .then(), it passes along the promise chain
    .then() 메서드가 항상 결과값으로 프로미스만 리턴할 필요는 없다. 예를 들어 한 번 string 형태로 만들어진다고 해도 프로미스 체인은 문제 없이 굴러간다.

예를 들어 이렇게 .then() 결과값으로 프로미스로 반환되지 않는 경우에도 에러가 발생하지 않는다.

getDataPromise(10).then((data) => {
  return getDataPromise(data)
}).then((data) => {
  // return getDataPromise(data)
  return 'This is some test data'
}).then((data) => {
  console.log(data)
}).catch((err) => {
  console.log(err)
})
//This is some test data
profile
빵굽는 프론트엔드 개발자

0개의 댓글