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 필드를 활용해 서버에 추가 정보를 보낸다
'TIL > 엘리스 SW 엔지니어 트랙 2기' 카테고리의 다른 글
[5주차] 20220411 엘리스 TIL (비동기 복습, Node.js) (0) | 2022.06.30 |
---|---|
[4주차] 20220429 엘리스 TIL (JavaScript 심화) (0) | 2022.06.30 |
[4주차] 20220427 엘리스 TIL (JavaScript 심화) (0) | 2022.06.30 |
[2주차] 20220412 엘리스 TIL (JavaScript) (0) | 2022.06.30 |
[2주차] 20220413 엘리스 TIL (JavaScript) (0) | 2022.06.30 |
댓글