async function fetchUser(){
// 데이터를 받아오는데 10초 정도 걸린다고 가정
return 'hyunho'
}
const user = fetchUser()
user.then(console.log)
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}`)
})
}
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}` // 다 받은 후 실행
Request Response 구조
클라이언트는 서버에 요청을 보내고, 응답을 대기하고, 서버는 요청에 대한 결과를 만들어서 응답한다.
Q. 클라이언트와 서버를 분리하는 게 좋은 이유는?
A. 비즈니스 로직, 데이터는 서버에 사용성, UI는 클라이언트에 집중시킬 수 있다.
→ 클라이언트와 서버가 각각 독립적으로 진화하는 것이 가능하다.
Stateful vs. Stateless
Stateful: 항상 같은 서버가 유지되어야 한다.
Stateless: 상태를 보관하지 않기 때문에 아무 서버나 호출해도 된다.
지속 연결
연결 후 HTML, javascript, css 등의 파일을 모두 응답 받은 후 종료
HTTP-message = start-line
*( header-field CRLF )
CRLF
[ message-body ]
method SP request-target SP HTTP-version CRLF
GET /search?q=hello&hl=ko HTTP/1.1
HTTP-version SP status-code SP reason-phrase CRLF
HTTP/1.1 200 OK
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
XMLHttpRequest는 사용법이 복잡하고, 코드도 깔끔하지 못했습니다. 그래서 XMLHttpRequest를 대체하기 위해 자바스크립트는 ES6 부터 Fetch API를 비동기 처리의 표준으로 채택했습니다. Fetch API는 브라우저 내부에 내장되어있기 때문에, 다른 라이브러리처럼 설치과정이 없어도 이용할 수 있다는 장점도 가지고 있습니다.
Fetch API는 네트워크의 Request와 Response에 대한 객체를 제공하는데, 메소드가 fetch()하나 뿐 입니다. 이 메소드는 프로미스 객체를 반환하는데, 요청의 성공/실패에 관계없이 반환된 프로미스 객체로 부터 Response 객체를 취득할 수 있습니다.
fetch(url, options)
첫 번째 인수로 취득할 요소의 url을 받습니다. 이 url은 필수 인수입니다. 두 번째 인수인 options는 HTTP 요청 방식, 요청 헤더, 요청 본체 등을 설정할 수 있습니다.
fetch는 사용될 때는 아래와 같은 구조를 갖고 실행됩니다.
fetch(url, (options))
.then((res)=> {
//url로부터 fetch의 호출이 성공했을 때의 동작
})
.catch((error)=>{
//url로부터 fetch의 호출이 실패했을 때의 동작
});
fetch의 호출 성공시 응답하는 객체인 res(Response)에서는 HTTP 상태, 응답 헤더, 응답 본체 등을 취득할 수 있습니다.
HTTP 통신 방식에는 대표적으로 GET, POST가 있습니다. GET은 클라이언트가 서버에서 데이터를 얻고자 할 때 사용하는 방식, POST는 클라이언트가 서버의 데이터를 추가하거나 수정할 때 사용하는 방식입니다.
fetch는 GET방식일 때와 POST방식일 때 사용방법이 조금 다릅니다.
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 방식임을 옵션에 알리고, 전송하는 데이터 포맷을 지정해주어야합니다. 대표적으로 요즘 웹 통신에서 많이 사용되는 JSON을 예로 들어보겠습니다.
fetch(url, {
method: "POST",
headers: {
//JSON 이용시, 헤더에 JSON을 이용한다고 알려야함!
//+헤더에 넣고싶은 내용
},
body: {
//JSON 이용시 body를 반드시 직렬화 해주어야 합니다.(JSON.stringfy)
//바디에 넣고싶은 내용들
}
})
.then((res)=> {
//url로부터 fetch의 호출이 성공했을 때의 동작
})
.catch((error)=>{
//url로부터 fetch의 호출이 실패했을 때의 동작
});