TIL 35. fetch 함수와 프로미스 체이닝

CHAEIN·2021년 7월 30일
1

JavaScript

목록 보기
27/31
post-thumbnail

1. fetch 함수

fetch(url)가져오다라는 뜻으로 파라미터로 넘어오는 url로 서버에 request를 보내서 원하는 내용을 가져오고 response를 받는 역할을 수행한다.

fetch("https://jsonplaceholder.typicode.com/users")
  .then((response) => response.text())
  .then((result) => {
    console.log(result);
  });

then 메소드는 앞에서 리턴한 값을 response로 받아 처리한다.서버가 보낸 response는 하나의 객체가 되어 then 메소드의 파라미터로 넘어온다.

2. fetch 함수와 프로미스 객체

fetch 함수는 promise객체를 리턴한다. promise 객체란 어떤 작업에 관한 상태정보를 가지고 있는 객체이다.

promise 객체는 3가지 상태를 가진다.

  1. pending -> 작업이 진행중
  2. fulfilled -> 작업이 성공적으로 완료됨
  3. rejected -> 작업이 실패함
fetch("https://jsonplaceholder.typicode.com/users")

fetch 함수가 리턴한 프로미스 객체는 처음엔 pending 상태이다. 작업이 완료된 response 를 받으면 fulfilled 상태로 바뀌고 작업 성공 결과를 갖게 된다. 어떠한 이유에서 request가 제대로 되지 않거나 서버 문제로 response를 받지 못했을 경우 rejected 상태가 되고 작업 실패에 대한 정보를 갖게된다.

.then((response) => response.text())

모든 then 메소드는 프로미스 객체를 리턴한다. 앞선 fetch 함수가 리턴한 작업 성공결과는 then 메소드의 첫번째 파라미터인 response에 넘어온다. 이 때 넘어온 promise객체가 fulfilled 상태이면 미리 등록해둔 콜백함수가 실행된다.

3. then 메소드와 Promise 체이닝

fetch("https://jsonplaceholder.typicode.com/users") // 프로미스 객체 리턴
  .then((response) => response.text()) // .text 메소드는 프로미스 객체를 리턴하는 메소드이다.
  .then((result) => {
    const users = JSON.parse(result);
    return users[0];
  })
  .then((user) => {
    console.log(user);
    const { address } = user;
    return address;
  })
  .then((address) => {
    console.log(address);
    const { geo } = address;
    return geo;
  })
  .then((geo) => {
    console.log(geo);
    const { lat } = geo;
    return lat;
  })
  .then((lat) => {
    console.log(lat);
  });

fetch 함수의 then 메소드가 또다른 프로미스 객체를 리턴하기 때문에 뒤에 then 메소드를 이어나갈 수 있다. then 메소드가 리턴한 promise 객체는 처음엔 pending 상태이다. 그러나 내부 콜백 함수가 실행되고 콜백에서 어떤 값이 리턴되면 then 메소드가 리턴한 프로미스 객체가 영향을 받는다. 이 때 콜백에서 어떤 값을 리턴하는냐에 따라 받는 영향이 달라진다.

1) 콜백 안에서 promise 객체를 리턴하는 경우
then 메소드가 리턴한 프로미스 객체는 콜백이 리턴한 프로미스 객체와 동일한 상태와 값을 갖게 된다. 콜백이 리턴한 프로미스 객체가 fulfilled 상태가 되면 then 메소드의 프로미스 객체도 fulfilled 상태가 되며 동일한 작업 성공결과를 갖게되고 콜백이 리턴한 프로미스 객체가 rejected 상태가 되면 then 메소드의 프로미스 객체도 rejected가 되어 작업 실패 정보를 갖게 된다.

2) promise 객체가 아닌 값을 리턴하는 경우
콜백이 숫자, 문자열, 객체같이 프로미스 객체가 아닌 값을 리턴하면 then 메소드의 프로미스 객체는 fulfilled 상태가 되고 콜백이 리턴한 값을 작업 성공 결과로 갖게된다.

4. 프로미스 체이닝이 필요한 이유

비동기 작업을 순차적으로 실행시키고자 할 때 콜백 헬 현상을 방지하고 전체 작업을 보다 깔끔하게 표현하기 위하여 사용한다.

console.log("Start!");

fetch("https://jsonplaceholder.typicode.com/users")
  .then((response) => response.text())
  .then((result) => {
    let users = JSON.parse(result);
    let { id } = users[0];
    fetch(`https://jsonplaceholder.typicode.com/posts?userID=${id}`)
      .then((response) => response.text())
      .then((posts) => console.log(posts));
  });

console.log("End!");

// ==> 프로미스 체이닝을 활용한 리팩터링

console.log("Start!");

fetch("https://jsonplaceholder.typicode.com/users")
  .then((response) => response.text())
  .then((result) => {
    let users = JSON.parse(result);
    let { id } = users[0];
    fetch(`https://jsonplaceholder.typicode.com/posts?userID=${id}`);
  }) // ==> 이 이후부터는 두번째 fetch 함수가 리턴한 프로미스객체에 then이 연결된 방식과 같다.
  .then((response) => response.text())
  .then((posts) => console.log(posts));

console.log("End!");

위 코드를 아래처럼 변경할 수 있는 이유는 then 메소드에서 리턴한 프로미스 객체가 콜백 함수에서 리턴한 프로미스 객체와 동일한 상태와 값을 가지기 때문이다.

<참고> Axios와 fetch 함수

ajax 통신을 할 수 있는 함수로는 fetch 말고도 axios 패키지가 있다. axios 또한 프로미스 객체를 리턴하며 사용방법도 fetch 함수와 비슷하다.

axios
  .get("https://jsonplaceholder.typicode.com/users")
  .then((response) => {
    console.log(response);
  })
  .catch((error) => {
    console.log(error);
  });

axios는 fetch 함수에는 없는 다음과 같은 몇가지 기능들이 있다.

  • 모든 리퀘스트, 리스폰스에 대한 공통 설정 및 공통된 전처리 함수 삽입 가능
  • serialization, deserialization을 자동으로 수행
  • 특정 리퀘스트에 대해 얼마나 오랫동안 리스폰스가 오지 않으면 리퀘스트를 취소할지 설정 가능(request timeout)
  • 업로드 시 진행 상태 정보를 얻을 수 있음
  • 리퀘스트 취소 기능 지원

그러나 외부 라이브러리 라는 점에서 별도의 패키지 다운로드가 필요하다.

0개의 댓글