본문 바로가기
TIL/엘리스 SW 엔지니어 트랙 2기

[4주차] 20220428 엘리스 TIL (JavaScript 심화)

by VANAV 2022. 6. 30.

04 async / await

  • async / await
    • Promise를 활용한 비동기코드를 간결하게 작성하는 문법 (syntactic sugar 라고도 함)
    • async/await 문법으로 비동기코드를 동기코드처럼 간결하게 작성할 수 있다.
    • async 함수와 await 키워드를 이용한다
    • await 키워드는 반드시 async 함수 안에서만 사용해야 한다
    • async 로 선언된 함수는 반드시 Promise를 리턴한다
  • async 함수
async function asyncFunc() {
	let data = await fetchData()
    let user = await
  fetchUser(data)
	return user
}
  • async 함수는 function 키워드 앞에 async를 붙여 만든다
  • async 함수 내부에서 await 키워드를 사용한다
  • fetchData, fetchUser는 Promise를 리턴하는 함수이다
  • await 키워드 실행 순서
async function asyncFunc() {
	let data1 = await fetchData1()
    let data2 = await fetchData2(data1)
    let data3 = await fetchData3(data2)
    return data3
}
function promiseFunc(){
	return fetchData1()
    	.then(fetchData2)
        .then(fetchData3)
}
  • await 키워드는, then 메서드 체인을 연결한 것처럼 순서대로 동작한다
  • 비동기 코드에 쉽게 순서를 부여한다.
  • 에러 처리
function fetchData1() {
	return request()
    .then((response) => 
	response.requestData)
    .catch(error => {
    //error 발생
    })
}
  • Promise를 리턴라는 함수의 경우, 에러가 발생하면 catch 메서드를 이용하여 에러를 처리한다
  • catch 메서드를 사용하지 않는다면 async 함수에서 try-catch 구문을 이용하여 에러를 처리한다
// try-catch 구문으로 에러처리한 사례

async function asyncFunc() {
	try {
    	let data1 = await
fetchData1()
		return fetchData2(data1)
    }catch(e){
    	console.log("실패: ", e)
    }
}

지금 구문은

try
   fd1
   fd2
catch

fd1 과 fd2 의 에러처리가 catch에 한꺼번에 묶여서 처리되고 있다.

 

(fetchData2(data1)에 await 키워드가 있다고 가정했을 때)

만약 에러처리를 더 다분화하고 싶다면?

(ex> fd1 = 유저정보 / fd1에서 에러가 난다면? '유저정보를 가져오지 못했습니다' 라고 출력하고 싶고

fd2 = 주소 / fd2에서 에러가 난다면? '주소를 가져오지 못했습니다' 라고 출력하고 싶다면?)

 

try
   fd1
catch
try
   fd2
catch

로 나눠서 세분화된 에러처리도 가능하다.

 

[퀴즈]

 

await 키워드로 비동기 처리에 순서를 부여한다. ⭕

await 키워드는 여러 개가 쓰였을 시 뒤쪽 코드를 Promise의 .then() 함수를 사용하는 것처럼 만들어, 비동기 처리에 순서를 부여합니다.

에러가 발생했을 경우 try-catch 구문으로 에러를 처리할 수 있다. ⭕

try-catch 구문으로 비동기 코드의 에러 또한 처리할 수 있습니다.

async 함수 내부의 코드 실행은 동기적이다. ❌

async 함수는 동기적으로 보이지만 비동기적으로 실행됩니다. 단, 내부에서 await 키워드가 쓰이지 않았을 경우엔 Promise.resolve() 로 처리됩니다.

await 키워드는 반드시 프로미스를 리턴하는 함수에만 사용한다.

await 키워드는 프로미스를 리턴하지 않는 함수라도 사용할 수 있습니다. 단 이 경우 리턴한 데이터는 Promise.resolve()로 감싸집니다.

 

05. HTTP, REST API

  • HTTP(Hypertext Transfer Protocol)
    • Web에서 서버와 클라이언트 간의 통신하는 방법을 정한 것
    • 클라이언트는 웹 브라우저 등 서버로 요청을 보내는 대상
    • 서버는 클라이언트가 요청을 보내기 전까지 대응하지 않음
    • 서버와 클라이언트 사이에는 무수히 많은 요소가 존재
    • HTTP는 이런 존재들 사이의 통신 방법을 규정
  • HTTP Message
    • 서버 주소, 요청 메서드(POST), 상태 코드(403, 404...), target path, 헤더 정보, 바디 정보 등이 포함
    • 요청 메시지, 응답 메시지의 모양이 다름
    • HTTP/1.1 메시지는 사람이 읽을 수 있음(통신상태를 보고 어떤게 문제점인지 파악할 수 있다) / HTTP2 의 fail load의 경우, 내용물을 사람이 읽는건 불가능하다
  • HTTP Header
    • HTTP 메시지의 헤더에는 콘텐츠 관련 정보(ex> JSON 페이로드, form 데이터, 파일 정보(파일 업로드)), 인증 관련 정보(Autorization - 이 정보를 통해 사용자 로그인 등을 파악 가능), 쿠키 정보(보안에 취약한 정보가 아니라 좀 가벼운 정보(ex> 검색 기록 등)), 캐시 관련 정보(ex> 서버가 페이지 응답을 내릴 때 헤더에 정보를 내린다(페이지 재사용을 위해)) 등 서버와 클라이언트 간 통신 시 필요한 정보를 담는다
    • 클라이언트 요청 시, 서버 응답 시 모두 헤더에 정보를 담을 수 있다
  • HTTP Status
    • HTTP 요청 시, 클라이언트는 요청의 결과에 대한 상태 정보를 얻는다(결과가 잘되었거나(서버와 클라이언트간 통신이 잘 이루어졌다던가) 잘 안되었거나(페이지를 찾았는데 존재하지 않는다던가) 하는 상태).
    • 200, 400, 500 등 숫자 코드와, OK, NOT FOUND 등의 텍스트로 이루어짐
    • 코드를 이용해 각 결과에 해당하는 행위를 할 수 있음
  • 요청 메서드
    • HTTP에서, 클라이언트는 서버로 요청을 보낸다
    • 요청시, 요청 메서드로 특정 요청에 대한 동작을 정의한다
    • GET, POST, PUT, PATCH, DELETE, OPTIONS, CONNECT, TRACE 등이 규정됨(HTTP에서는 그저 가짓수를 정의한 것 / 의미부여는 REST API 에서!)
    • GET(가져온다), POST(서버에 어떤 내용을 붙인다(생성)), PUT(POST와 비슷 / 기존에 존재하는 정보를 새롭게 업데이트 한다), PATCH(기존에 존재하는 정보를 새롭게 업데이트한다), DELETE(정보를 삭제하고 싶다) = 직접 커스텀해서 사용하는 부분(요청에 의미를 부여하는 메서드) - 이런 통신에 대한 의미부여는 반드시 서버의 구현에 직접적인 영향을 미친다고는 할 수 없다. 단순히 우리가 통신규약을 만든것일 뿐 어떻게 활용하느냐는 개발자의 몫임
    • OPTIONS, CONNECT, TRACE = 브라우저에서 자동으로 처리해주는 부분
  • REST API(Representational State Transfer API)
    • API(Application Programming Interface)는 사용자가 특정 기능을 사용할 수 있도록 제공하는 함수를 의미한다
    • REST API는 HTTP의 요청 메서드에 응하는 서버 API와 클라이언트 간 통신의 구조가 지켜야 할 좋은 방법을 명시한 것이다.
    • 구체적인 내용으로는 요청 메서드의 의미, URI 설계, 클라이언트의 상태에 대한 동작 등을 정의한다
    • HTTP = 단순히 통신 규약 / REST API = 그 규약을 어떻게하면 잘 사용해서 서버와 클라이언트간 통신을 잘 구축할 수 있는가
  • REST API 요청 메서드의 의미
    • GET - 리소스 정보를 얻음
    • POST - 리소스를 생성
    • PUT - 리소스를 생성하거나 업데이트
    • DELETE - 리소스를 제거

 

06 Fetch API

  • Fetch API (HTTP를 활용할 수 있음)
let result = fetch(serverURL)

result
	.then(response => {
    if(response.ok){
    //요청 성공
    }
})
	.catch(error => {
    //요청 실패
    })
  • 기존 XMLHTTPREquest를 대체하는 HTTP 요청 API
  • ES6에 추가된 Promise를 리턴하도록 정의됨
  • 네트워크 요청 성공시, Promise는 Response 객체(response 라는 이름은 중요하지 않다)를 resolve 한다
  • 네트워크 요청 실패시, Promise는 에러를 reject 한다

 

  • Response
fetch(serverURL)
	.then(response => {
    	response.ok
        response.status
        response.statusText
        response.url
        response.bodyUsed
    })
  • Response 객체는 결과에 대한 다양한 정보를 담는다
  • response.ok는 HTTP Status code가 200-299 사이면 true, 그 외 false 이다
  • response.status는 HTTP status code를 담는다
  • response.url은 요청한 URL 정보를 담는다

 

  • Header
fetch(serverURL)
	.then(resp => {
    	for(let [k,v] of resp.headers){
        	console.log(k,v)
        }
    })
  • response.headers로 Response 객체의 헤더 정보를 얻을 수 있다(위 예시에선 for 문을 통해서)

 

  • Body 메서드
fetch(serverURL)
	.then(response => {
    	return response.json()
    })
    .then(json => {
    	console.log('body : ', json)
    })
  • response.json() 메서드는 얻어온 body 정보를 json 으로 만드는 Promise를 반환한다(한번 더 then chain을 통해서 promise를 resolve 해서 그 정보를 사용해야만 한다)
  • Promise가 resolve 되면 얻어온 body 정보를 읽는다
  • response.text(), response.blob(), response.formData() 등의 메서드로 다른 형태의 바디를 읽는다

 

  • POST 요청
fetch(serverURL, {
	method: 'post',
    headers: {
    	'Content-Type':
    'application/json;charset=utf-8',
    Authentication: 'mysecret' //이렇게 header에 secret을 넣어줄 수 있다
    },
    body: JSON.stringify(formData)
})
	.then(response => {
    	return response.json()
    })
    .then(json => {
    	console.log('POST 요청 결과:' , json)
    })
  • fetch(url, options(둘다 fetch API)) 로, fetch 메서드 옵션을 넣는다
  • method 필드로 여러 요청 메서드를 활용한다
  • headers, body 필드를 활용해 서버에 추가 정보를 보낸다

 

댓글