자바스크립트 8

hee_hee_·2023년 1월 13일
0

딩..딩..

목록 보기
13/15
post-thumbnail

1. async/await

Promise를 활용한 비동기 코드를 간결하게 작성하는 문법.
프로미스로 비동기 코드를 구현하면 직관적이지 않아서 간결하게 직관적으로 작성할 수 있다.
비동기 코드를 동기 코드처럼 간결하게 작성할 수 있다.
async 함수와 await 키워드를 이용
await 키워드는 async가 있어야만 사용 가능함.
async 함수는 반드시 promise를 리턴한다.

형태

async function 함수이름(){ }

예제

acync function a () {
	let data = await fetchData()
	let name = await fetchName(data)
	return name
}

async함수는 function 키워드 앞에 붙여서 만든다.
내부에는 await 키워드를 사용하고
안에 fetchData,Name 같은 경우는 promise를 리턴하는 함수.
예를 들어 function FD(){return new Promise...}


순서

await 키워드는 then 메서드 체인을 연결한 것처럼 순서대로 동작한다.
=> 따라서 비동기 코드에 순서를 부여.


에러 처리

async 의 경우 promise를 리턴하는 함수일 경우, 에러가 발생하면 catch 메서드를 이용해서 에러를 처리한다.

.catch( error => {
	console.log(err)
})

catch 메서드를 사용하지 않는다면 try-catch 구문을 이용해 에러를 처리함.

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

catch 절의 e 는 promise 의 catch 메서드가 받는 반환 값과 동일

각각 별도로 에러처리를 하고 싶다면 각각 try-catch 해주면 됨




2. HTTP, REST API

HTTP (Hypertext Transfer Protocol)

web에서 서버와 클라이언트 간 통신하는 방법을 정한 것.

  • 클라이언트 : 웹 브라우저 등 서버로 요청을 보내는 대상
  • 서버 : 클라이언트가 요청을 보내는 것을 받아 요청받은 것을 보내줌. 클라이언트가 요청을 보내기 전까지 대응하지 않음.

서버와 클라이언트 사이에는 무수히 많은 요소가 존재하며
HTTP는 이런 존재들 사이의 통신 방법을 규정함

HTTP message

메세지에는
서버 주소, 요청 메서드, 상태 코드, target path, 헤더 정보, 바디 정보
등이 포함되어 있음
host 에 서버주소가 포함되어 있음
요청 메서드는 post 등
상태 코드는 404 등 등
target path 는 /

요청 메세지와 응답 메세지의 모양이 다르고
HTTP/1.1 메세지는 사람이 읽을 수 있다.

=> 통신 상태를 보고 어떤 문제점이 있는지 파악할 수 있다.

이것은 통신 규약이라 버전에 따라 통신 방법이 조금 달라진다.

HTTP header

콘텐츠 관련 정보, 인증 관련 정보, 쿠키 정보, 캐시 관련 정보 등
서버와 클라이언트 간 통신 시 필요한 정보를 담고 있음.

클라이언트 요청 시 서버 응답 시 모두 헤더에 정보를 담을 수 있다.

HTTP status

HTTP 요청 시 클라이언트는 요청의 결과에 대한 상태 정보를 얻는다.
200,400,500 등 숫자 코드와 OK, NOT FOUND 등의 텍스트로 이루어져 있다.
코드를 이용해 각 결과에 해당하는 행위를 할 수 있음.

요청 메세드

HTTP에서 클라이언트는 서버로 요청을 보낸다.
GET, POST, PUT, PATCH, DELETE, OPTIONS, CONNECT, TRACE 등 규정되어 있음.
요청시 요청 매서드로 특정 요청에 대한 동작을 정의함

REST API

API(Application Programming Interface)는 사용자가 특정 기능을 사용할 수 있도록 제공하는 함수

REST API는 HTTP 요청 메서드에 응하는
서버API와 클라이언트 간 통신의 구조가 지켜야 할 좋은 방법을 명시한 것.

구체적인 내용으로는 요청 메서드의 의미, URL설계, 클라이언트의 상태에 대한 동작 등을 정의함.

http가 단순히 통신 규약. rest api는 어떻게 하면 그 규약을 잘 사용해서 서버와 클라이언트 간 통신을 구축할 수 있는가에 대한 내용.

REST API 요청 메서드의 의미

  • GET : 리소스 정보 얻음
  • POST : 리소스 생성
  • PUT : 리소스 생성 또는 업데이트
  • DELETE : 리소스 제거



3. Fetch API

기존에 쓰던 XMLHTTPRequest를 대체하는 HTTP 요청 API
거기에 추가로 Promise를 리턴하도록 정의됨.

fetch 는 네트워크 요청에 성공하면 Promise가 Response 객체를 resolve하게 된다.
네트워크 요청에 실패하면 Promise는 에러를 reject 한다.

let result = fetch('URL')

result
	.then ( response => {
    	if (response.ok) {
    	요청 성공
        }
	})
    .catch ( error => {
    	요청 실패
    })

Response

response 객체는 이름은 중요하지 않고 어떤 프로퍼티를 가지고 있느냐가 중요함.

fetch('URL')
	.then(response =>{
    	response.ok
        response.status
        response.url
    })

Response 객체는 결과에 대한 다양한 정보를 담는데
ok의 경우 status code가 200번대면 true, 아니면 false이고
status는 HTTP status code를 담고
url 은 요청한 url 정보를 담는다.

fetch('URL')
	.then(response =>{
    	for (let [k, v] of response.headers) {
        console.log(k,v)
     	}
    })

response.headers로 Response 객체의 헤더 정보를 얻을 수 있다.

Body 메서드

fetch('URL')
	.then(response =>{
    	return response.json()
    })
    .then(json => {
 		console.log('body :', json)   
    })

response.json() 메서드는
얻어온 body 정보를 json으로 만드는 promise를 반환한다.
promise가 resolve되면 얻어온 body 정보를 읽는다.

response.text(), response.blob(), response.formData() 등의 메서드로
다른 형태의 바디를 읽는다.

POST 요청

fetch('URL', {
	method : 'post',
    headers : {
    	'Content-Type': 'application/json;carset=utf-8',
        Authentication : 'mysecret'
    },
    body : JSON.stringify(formData)
        
})
	.then(response => {
    	return response.json()
    })
    .then(json => {
    	console.log('POST 요청 결과:',json)
    })

fetch API는 옵션을 넣을 수 있음.

fetch('url',options)

fetch 메서드 옵션을 넣어서 method 필드로 여러 요청 메서드를 활용할 수 있음.
headers, body 필드를 활용해 서버에 추가 정보를 보낼 수도 있음.




콜백(callback)함수 이해와 promise, async/await 활용하기

function getName(cb) {
    setTimeout(() => {
         cb("riri")
    }, 5000);
}

getName((name) => {
     console.log(name);
})

getName은 이름을 인자로 받아 콘솔에 출력을 함.
앞의 비동기함수는 콜백으로 getName을 사용. 이름에 riri를 넘겨 5초 뒤 실행.
riri가 5초 뒤에 콘솔창에 찍힘.

만약 비동기 함수가 여러개라면

function getName(cb) {
    setTimeout(() => {
         cb("riri")
    }, 5000);
}
function getAge(cb) {
    setTimeout(() => {
         cb(5)
    }, 5000);
}
function getAddress(cb) {
    setTimeout(() => {
         cb("star")
    }, 5000);
}
getName ((name)=>{
    getAge ((age)=>{
        getAddress((address)=>{
             console.log(name, age, address)
        })
    })
})

이런식으로 한번에 접근 가능하며, 각 함수가 실행되는데 5초가 걸리므로 15초 뒤에 riri 5 star 가 출력된다.

이것을 promise를 활용해 바꾸면

function getName(cb) {
    return new Promise((resolve) => {
         setTimeout(() => {
              resolve("riri");
         }, 5000);
    })
}


function getAge(cb) {
    return new Promise((resolve) => {
         setTimeout(() => {
              resolve(5);
         }, 5000);
    })
}

function getAddress(cb) {
     return new Promise((resolve) => {
         setTimeout(() => {
             resolve('star');
         }, 5000);
     })
}

이렇게 수정이 되고 각 함수는 promise 객체를 리턴하는데 항상 5초 뒤 resolve 되어 정보를 준다.

호출은


getName().then((res)=>{
      console.log(res);
})
getAge().then((res)=>{
      console.log(res);
})
getAddress().then((res)=>{
      console.log(res);
})

이렇게도 할 수 있고

Promise
   .all([getName(),getAge(),getAddress()])
   .then((res)=>{
        const[name,age,address] = res;
        console.log(name,age,address)
   })

이렇게도 가능하다.
.all은 인자로 배열을 받고 그 배열의 원소는 모두 프로미스 객체이고 병렬적으로 배열의 원소에 있는 프로미스를 동시에 실행시킨다.
따라서 5초 후 riri 5 star 가 출력된다.

이것을 더 간단하게 async/await를 사용하면

(async ()=>{
    const name = await getName();
    const age = await getAge();
    const address = await getAddress();
    
    console.log(name,age,address);

})();

즉시 실행 함수 형태의 화살표 함수를 이용해 작성 가능함.
await가 프로미스가 resolve 될 때까지 기다린 후 다음순서로 넘어가기 때문에
15초 뒤에 riri 5 star 출력된다.

profile
딩코딩코딩

0개의 댓글