JS - Fetch

아침7시개발·2021년 12월 24일
1

Js

목록 보기
1/4

AJAX란?

JavaScript의 라이브러리 중 하나이며,
Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml의 약자)이다.
AJAX는 JavaScript를 사용한 비동기 통신, 클라이언트와 서버 간에 XMLHttpRequest 데이터를 주고받는 기술이라고 할 수 있다.

XMLHttpRequest란?

대부분의 웹 브라우저에서는 서버로부터 데이터를 요청하는 XML 객체들을 내장하고 있다.
XMLHttpRequest를 이용하면 웹 페이지를 전부 로딩하고도 서버로부터 데이터를 요청하거나 전송받을 수 있으며, 웹 페이지를 전부 로딩하지 않고도 일부만을 갱신하는 게 가능해진다.

Promise란?

프로미스는 자바스크립트 비동기 처리에 사용되는 객체다.
여기서 자바스크립트의 비동기 처리란 ‘특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성’을 의미한다.

기본 구조

function getData(callbackFunc) {
  $.get('url 주소/products/1', function(response) {
    callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
  });
}

getData(function(tableData) {
  console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});

프로미스 적용

function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});

프로미스의 3가지 상태(states)

프로미스를 사용할 때 알아야 하는 가장 기본적인 개념이 바로 프로미스의 상태(states)다. 여기서 말하는 상태란 프로미스의 처리 과정을 의미한다. new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖는다.

  • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
  • Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
  • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

Pending(대기)

new Promise(function(resolve, reject) {
  // ...
});

Fulfilled(이행)

new Promise(function(resolve, reject) {
  resolve();
});

Rejected(실패)

new Promise(function(resolve, reject) {
  reject();
});

실패 했을 때 처리

function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("Request is failed"));
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
  console.log(err); // Error: Request is failed
});

여러 개의 프로미스 연결하기 (Promise Chaining)

function getData() {
  return new Promise({
    // ...
  });
}

// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
  .then(function(data) {
    // ...
  })
  .then(function() {
    // ...
  })
  .then(function() {
    // ...
  });

프로미스 에러 처리는 가급적 catch()를 사용

// then()의 두 번째 인자로는 감지하지 못하는 오류
function getData() {
  return new Promise(function(resolve, reject) {
    resolve('hi');
  });
}

getData().then(function(result) {
  console.log(result);
  throw new Error("Error in then()"); // Uncaught (in promise) Error: Error in then()
}, function(err) {
  console.log('then error : ', err);
});

fetch란?

fetch 매서드는 JavaScript에서 서버로 네트워크 요청을 보내고 응답을 받을 수 있도록 해주는 매서드이다.
XMLHttpRequest와 비슷하지만 fetch는 Promise를 기반으로 구성되어 있어서 더 간편하게 사용할 수 있다는 차이점이 있다.

기본 구조

fetch(url)
.then(res => {
  console.log(res)
})
.catch(error => {
  console.log(error)
})

기본적인 구조와 동작은 Promise 객체와 동일하다.
then에서 응답 객체 res를 받고, catch에서 에러 요청이 발생했을 때, 에러를 받는다.

요청 정보 파라미터

fetch(url, {
   method: 'post',
   headers: {
     "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
   },
   body: 'foo=bar&lorem=ipsum'
})
.then(res => {
  console.log(res);
})
.catch(error => console.log(error));
  • method : HTTP method와 동일하며 요청 방식을 나타낸다. (GET, POST, PUT, DELETE 등)
  • headers : 요청 헤더에 대한 정보를 나타낸다.
  • body : 요청을 보내는 데이터를 나타낸다. 여러 가지 자료형을 대입할 수 있다.

fetch 파라미터로 직접 입력하기도 하지만 주로 객체 변수에 저장해서 대입하는 방식으로도 사용한다.

let obj = {
    method: 'post',
    headers: {
      "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
    },
    body: 'foo=bar&lorem=ipsum'
}
fetch(url, obj)
.then(...)

POST 요청 보내고 응답받기

fetch(url, {
  method: 'POST',
  body: JSON.stringify({ name: "hello!" })
})
.then(res => {
  if (res.status === 200) {
    res.text().then(text => console.log(text)
  }
  else {
    console.log(res.statusText)
  }
})
.catch(err => console.log(err))
  • POST로 body안에 데이터를 넣고, 요청을 보내주면 응답 객체 res를 받게 되는데 res 안에는 응답에 관한 정보가 존재한다.
  • status는 요청이 성공인지 실패인지를 판별할 수 있게 해주는 요소이다.
  • 또 응답에 대한 내용은 res.text()를 통해 확인할 수 있다.
  • text() 외에도 arrayBuffer, blob, json, formData 등의 메서드를 사용하여 값을 볼 수도 있다.
  • GET, PUT, DELETE 요청도 같은 방식으로 보낼 수 있다.

async & await란

async와 await는 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법이다. 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와준다.

async & await 기본 문법

async function 함수명() {
  await 비동기_처리_메서드_명();
}
  • 먼저 함수의 앞에 async 라는 예약어를 붙인다.
  • 함수의 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 await를 붙인다. (비동기 처리 메서드가 꼭 프로미스 객체를 반환해야 await가 의도한 대로 동작함)
  • 프로미스 객체를 반환 하는 것은 Axios 등 프로미스를 반환하는 API 호출 함수가 있다.
function fetchItems() {
  return new Promise(function(resolve, reject) {
    var items = [1,2,3];
    resolve(items)
  });
}

async function logItems() {
  var resultItems = await fetchItems();
  console.log(resultItems); // [1,2,3]
}

Jquery에서 사용 예제

// HTTP 통신 동작을 모방한 코드
function fetchItems() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      var items = [1,2,3];
      resolve(items)
    }, 3000);
  });
}

// jQuery ajax 코드
function fetchItems() {
  return new Promise(function(resolve, reject) {
    $.ajax('domain.com/items', function(response) {
      resolve(response);
    });
  });
}

await를 사용하지 않았다면 데이터를 받아온 시점에 콘솔을 출력할 수 있게 콜백 함수나 .then()등을 사용해야 했을 것이다.
하지만 async await 문법 덕택에 비동기에 대한 사고를 하지 않아도 된다.

async & await 실사용 예제

function fetchUser() {
  var url = 'https://jsonplaceholder.typicode.com/users/1'
  return fetch(url).then(function(response) {
    return response.json();
  });
}

function fetchTodo() {
  var url = 'https://jsonplaceholder.typicode.com/todos/1';
  return fetch(url).then(function(response) {
    return response.json();
  });
}
async function logTodoTitle() {
  var user = await fetchUser();
  if (user.id === 1) {
    var todo = await fetchTodo();
    console.log(todo.title); // delectus aut autem
  }
}
  1. fetchUser()를 이용하여 사용자 정보 호출
  2. 받아온 사용자 아이디가 1이면 할 일 정보 호출
  3. 받아온 할 일 정보의 제목을 콘솔에 출력

async & await 예외 처리

async function logTodoTitle() {
  try {
    var user = await fetchUser();
    if (user.id === 1) {
      var todo = await fetchTodo();
      console.log(todo.title); // delectus aut autem
    }
  } catch (error) {
    console.log(error);
  }
}

코드를 실행하다가 발생한 네트워크 통신 오류뿐만 아니라 간단한 타입 오류 등의 일반적인 오류까지도 catch로 잡아낼 수 있다. 발견된 에러는 error 객체에 담긴다.

출처

https://joshua1988.github.io/web-development/javascript/js-async-await/
https://ljtaek2.tistory.com/130

profile
쉬엄쉬엄하는 개발자

0개의 댓글