[엘리스 sw 엔지니어 트랙] 18일차 async/await, API, HTTP, Fetch API

오경찬·2022년 5월 4일
0

수업 18일차

Javascript의 마지막 실시간 수업이었다. 따리가기 급급했던거 같은데 벌써 Javascript를 끝내고 node.js로 넘어간다는게 충격적이였다. 열심히 하자 :)

이론

  • try / catch : 예외 처리를 위한 문법, try블럭 내에서 에러가 발생하면 catch블럭에서 처리할 수있음
    async function : 비동기 함수임을 선언 하는 함수, Promise객체를 반환
    await : async 함수 내에서만 사용 가능, promise가 완료될 때까지 다음 코드를 실행하지 않고 기다림
    HTTP : HTML같은 하이퍼미디어 문서를 전송하기 위한 프로토콜, 서버와 통신하는 것을 의미
    Debouncing : 연속적으로 호출되는 함수들 중 마지막 함수만 호출하는 기법
    Throttling : 새로운 이벤트가 발생했을 때, timer가 동작중이라면, 무시한느 방식
    API : 소프트웨어 간의 통신하기 위한 방법을 정의한것
    REST API : API의 디자인 원칙

Asyns / Awiat

async

  1. 자동적으로 함수 안에 있는 코드 블럭 들이 promise로 변환이 됩니다.
  2. 사용하는 방법은 함수 앞에 async 키워드를 연결 합니다.
async function fetchUser(){
    // 데이터를 받아오는데 10초 정도 걸린다고 가정
    return 'hyunho'
}

const user = fetchUser()
user.then(console.log)

await

  1. 자바스크립트는 await 키워드를 만나면, 프로미스가 처리 될 때 까지 기다립니다.
  2. 사용하는 방법은 async 가 붙은 함수 안에서만 사용할 수 있고, await 뒤에 붙은 코드를 기다립니다.
function delay(ms){
    return new Promise(resolve => setTimeout(resolve,ms))
    // 정해진 ms 가 지나면 resolve 리턴
}

async function getApple(){
    await delay(1000) // delay가 끝날 때 까지 여기서 기다립니다.
    return 'apple'
}

async function getBanana(){
    await delay(1000)
    return 'banana'
}

async function pick(){
    const apple = await getApple(); // apple를 받고
    const banana = await getBanana(); // banana를 받고
    return `${apple} + ${banana}` // 다 받은 후 실행
}

// async / await 를 사용하지 않고 기존의 promise 만 이용하는 경우
function pick(){
    return getApple()
    .then(apple => {
        return getBanana()
        .then(banana => `${apple} + ${banana}`)
    })
}

예외처리 (try-catch)

function delay(ms){
    return new Promise(resolve => setTimeout(resolve,ms))
    // 정해진 ms 가 지나면 resolve 리턴
}

async function getApple(){
    await delay(1000) // delay가 끝날 때 까지 여기서 기다립니다.
    return 'apple'
}

async function getBanana(){
    await delay(1000)
    return 'banana'
}

async function pick(){
    try{
        const apple = await getApple(); // apple를 받고
        const banana = await getBanana(); // banana를 받고
    } catch(error) {
        console.log(error)
    }
    return `${apple} + ${banana}` // 다 받은 후 실행

HTTP

  1. HTML같은 하이퍼미디어 문서를 전송하기 위한 프로토콜
  2. 웹에서 이뤄지는 모든 데이터 교환의 기초
  3. 서버와 통신하는 것을 의미

특징

1. 클라이언트 서버 구조

Request Response 구조
클라이언트는 서버에 요청을 보내고, 응답을 대기하고, 서버는 요청에 대한 결과를 만들어서 응답한다.

Q. 클라이언트와 서버를 분리하는 게 좋은 이유는?
A. 비즈니스 로직, 데이터는 서버에 사용성, UI는 클라이언트에 집중시킬 수 있다.
→ 클라이언트와 서버가 각각 독립적으로 진화하는 것이 가능하다.

2. 무상태 프로토콜 (stateless)

  1. 서버가 클라이언트의 상태를 보존하지 않는다.
  • 장점: 서버 확장성이 높다 (스케일 아웃에 유리) → 갑자기 클라이언트의 요청이 증가해도 서버를 대거 투입할 수 있다.
  • 단점: 클라이언트가 추가 데이터를 전송해야 한다.
  1. 상태 유지는 최소화하여 설계하는 것이 좋으며, 꼭 상태를 유지해야 하는 상황(로그인 등)에는 브라우저 쿠키와 서버 세션 등을 사용하여 상태를 유지한다.

    Stateful vs. Stateless
    Stateful: 항상 같은 서버가 유지되어야 한다.
    Stateless: 상태를 보관하지 않기 때문에 아무 서버나 호출해도 된다.

3. 비연결성 (connectionless)

  1. HTTP는 기본적으로 연결을 유지하지 않는 모델으로 불필요한 서버 자원 소모 없이 최소한의 자원을 사용하여 연결을 지원하며, 일반적으로 초 단위의 이하의 빠른 속도로 응답한다.
  2. 장점
  • 1시간 동안 수천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하인 경우가 많기 때문에, 서버 자원을 효율적으로 사용하는 것이 가능하다.
  1. 단점
  • 매번 TCP/IP 연결을 새로 맺기 때문에 3 way handshake 시간이 추가된다.
  • 웹 브라우저로 사이트를 요청하면 HTML 뿐만 아니라 javascript, css, 추가 이미지 등
    등 수 많은 자원이 함께 다운로드 되기 때문에 더 많은 시간이 낭비된다.
  • 현재는 HTTP 지속 연결(Persistent Connections)로 문제 해결을 해결하였으며, HTTP/2, HTTP/3에서 더 많은 최적화가 일어났다.

    지속 연결
    연결 후 HTML, javascript, css 등의 파일을 모두 응답 받은 후 종료

HTTP 메시지 구조

HTTP-message   = start-line
                 *( header-field CRLF )
                 CRLF
                 [ message-body ]

start-line

1. request-line

method SP request-target SP HTTP-version CRLF

GET /search?q=hello&hl=ko HTTP/1.1
  1. HTTP 메서드: 서버가 수행해야 할 동작을 지정한다.
  • GET: 리소스 조회
  • POST: 요청 내역 처리
  1. 요청 대상 (request-target)
  • absolute-path {?query} (절대경로{?쿼리})
    절대경로: "/" 로 시작하는 경로
  1. HTTP Version

2. status-line

HTTP-version SP status-code SP reason-phrase CRLF

HTTP/1.1 200 OK
  1. HTTP 버전
  2. HTTP 상태코드(status-code): 요청 성공 또는 실패 여부를 나타낸다.
  • 200: 성공
  • 400: 클라이언트 요청 오류
  • 500: 서버 내부 오류
  1. 이유 문구(reason-phrase): 사람이 이해할 수 있도록 짧게 상태 코드를 설명하는 문구
field-name ":" OWS field-value OWS 
  * OWS: Optional Whitespace
  * field-name은 대소문자를 구분하지 않는다.

Host: www.google.com
Content-Type: text/html;charset=UTF-8
Content-Length: 3423
  1. HTTP 전송에 필요한 모든 부가정보를 저장
  • e.g. 메시지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트(브라우저) 정보, 서버 애플리케이션 정보, 캐시 관리 정보
  1. 필요시 임의의 헤더를 추가할 수 있다.

message body

  1. 실제 전송할 데이터가 들어있다.
  2. HTML, 텍스트, 이미지, 음성, 영상, 파일, JSON, XML (API) 등 거의 모든 형태의 데이터 전송이 가능하다.
  3. 서버간에 데이터 통신에도 대부분 HTTP를 사용한다.

Fetch API

XMLHttpRequest는 사용법이 복잡하고, 코드도 깔끔하지 못했습니다. 그래서 XMLHttpRequest를 대체하기 위해 자바스크립트는 ES6 부터 Fetch API를 비동기 처리의 표준으로 채택했습니다. Fetch API는 브라우저 내부에 내장되어있기 때문에, 다른 라이브러리처럼 설치과정이 없어도 이용할 수 있다는 장점도 가지고 있습니다.

Fetch API는 네트워크의 Request와 Response에 대한 객체를 제공하는데, 메소드가 fetch()하나 뿐 입니다. 이 메소드는 프로미스 객체를 반환하는데, 요청의 성공/실패에 관계없이 반환된 프로미스 객체로 부터 Response 객체를 취득할 수 있습니다.

fetch()

fetch(url, options)

첫 번째 인수로 취득할 요소의 url을 받습니다. 이 url은 필수 인수입니다. 두 번째 인수인 options는 HTTP 요청 방식, 요청 헤더, 요청 본체 등을 설정할 수 있습니다.

fetch는 사용될 때는 아래와 같은 구조를 갖고 실행됩니다.

fetch(url, (options))
  .then((res)=> {
    //url로부터 fetch의 호출이 성공했을 때의 동작
  })
  .catch((error)=>{
    //url로부터 fetch의 호출이 실패했을 때의 동작
  });

fetch의 호출 성공시 응답하는 객체인 res(Response)에서는 HTTP 상태, 응답 헤더, 응답 본체 등을 취득할 수 있습니다.

GET, POST

HTTP 통신 방식에는 대표적으로 GET, POST가 있습니다. GET은 클라이언트가 서버에서 데이터를 얻고자 할 때 사용하는 방식, POST는 클라이언트가 서버의 데이터를 추가하거나 수정할 때 사용하는 방식입니다.

fetch는 GET방식일 때와 POST방식일 때 사용방법이 조금 다릅니다.

GET

GET방식은 처음 소개한 방식 그대로 이용합니다. 물론 options 인수에 GET방식임을 알려도 됩니다.

fetch(url)
  .then((res)=> {
    //url로부터 fetch의 호출이 성공했을 때의 동작
  })
  .catch((error)=>{
    //url로부터 fetch의 호출이 실패했을 때의 동작
  });

//또는
fetch(url, {
  method: "GET"
})
  .then((res)=> {
    //url로부터 fetch의 호출이 성공했을 때의 동작
  })
  .catch((error)=>{
    //url로부터 fetch의 호출이 실패했을 때의 동작
  });

POST

POST방식은 POST 방식임을 옵션에 알리고, 전송하는 데이터 포맷을 지정해주어야합니다. 대표적으로 요즘 웹 통신에서 많이 사용되는 JSON을 예로 들어보겠습니다.

fetch(url, {
  method: "POST",
  headers: {
    //JSON 이용시, 헤더에 JSON을 이용한다고 알려야함!
    //+헤더에 넣고싶은 내용
  },
  body: {
    //JSON 이용시 body를 반드시 직렬화 해주어야 합니다.(JSON.stringfy)
    //바디에 넣고싶은 내용들
  }
  })
  .then((res)=> {
    //url로부터 fetch의 호출이 성공했을 때의 동작
  })
  .catch((error)=>{
    //url로부터 fetch의 호출이 실패했을 때의 동작
  });
profile
코린이 입니당 :)

0개의 댓글