20230608 TIL

뿌링클 치즈맛·2023년 6월 11일
0

Elice AI트랙 8기

목록 보기
18/28

async / await

Promise를 활용한 비동기 코드를 간결하게 작성하는 문법 async/await 문법으로 비동기 코드를 동기 코드처럼 간결하게 작성할 수 있다. 그러나 async 함수 내부의 코드 실행이 비동기적인 것은 아니다. async로 선언된 함수는 반드시 Promise를 리턴한다.
async function asyncFunc() {
  let data = await fetchData()
  let user = await fetchUser(data){
  return user}
}

async는 function 키워드 앞에 async를 붙여 만든다.
async 함수 내부에서 await 키워드를 사용한다.
위 코드에서 fetchData,fetchUser는 프로미스를 반환하는 함수다!

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 => {
    //여기에 console.log('error')등을 넣을 수 있음
    // error 발생
  })
}

Promise를 리턴하는 함수의 경우, 에러가 발생하면 catch 메서드를 이용하여 에러를 처리한다. then의 두번째 콜백함수의 인자를 사용할 수도 있지만 catch를 사용하는 것이 좋다.catch 메서드를 사용하지 않는다면 async함수에서 try-catch 구문을 이용하여 에러를 처리할 수 있다.

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

try-catch 구문으로 async/await 형태의 비동기 코드 에러 처리가 가능하다.
catch 절의 e는, Promise의 catch 메서드가 받는 반환 값(error)과 동일하다.

Callback, Promise, async/await

콜백 함수

function getName(cb) {
    setTimeout(() => {
        cb("Elice");
      //getName의 인자로 받은 cb함수에 인자로 'Elice'를 전달
    }, 2000);
}

//함수 이해 안 가서 풀어씀
getNmae(function cb(name){
  console.log(name)
})

getName((name) => {
    console.log(name);
})
// 2초 후 Elice

위의 코드는 2초 뒤에 Elice를 출력한다.
getName의 인자인 cb는 setTimeout함수의 인자로 들어온 콜백함수인데, 'Elice'가 그 콜백 함수인 cb의 인자로 들어간 것이다. getName으로 name을 콘솔에 출력하려고 하면 name을 인자로 하는 익명함수 cb가 호출된다."cb(name)"
getName(function(name))을 살펴보면 cb는 console.log(name)를 실행 하는 함수로 getName에 있는 함수cb가 실행되기 전에 setTimeout이 실행되고, cb에 Elice가 전달된 다음 Elice가 출력되는 순서다. (맞는지 확인이 필요하다...)

콜백 지옥

function getName(cb) {
    setTimeout(() => {
        cb("Elice");
    }, 2000);
}

function getAge(cb) {
    setTimeout(() => {
        cb(6);
    }, 2000);
}

function getAddress(cb) {
    setTimeout(() => {
        cb("Seoul");
    }, 2000);
}

getName((name) => {
    getAge((age) => {
        getAddress((address) => {
            console.log(name, age, address)
          //총 6초 뒤 출력
        })
    })
})

위는 콜백을 3개 사용한 예시코드다. 겨우 3개지만 굉장히 복잡하다.

프로미스

function getName() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve("Elice");
        }, 2000);
    })
}
/*
//이해를 위해 풀어쓴 함수
function getName(){
  return new Promise(
  //상태가 fulfilled라면
  function(resolve){
    setTimeout(function(){
      resolve('Elice')},2000)
    	)
  	}
  )
}
*/

function getAge() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(6);
        }, 2000);
    })
}

function getAddress() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve("Seoul");
        }, 2000);
    })
}

getName,getAge,getAddress 3개의 함수는 모두 프로미스 객체를 반환한다. setTimeout에서 resolve가 호출되었으므로 이 프로미스는 fulfilled된 상태라고 생각한다.

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

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

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

함수들은 이렇게 호출해도 2초 뒤에 3가지가 동시에 출력되고,

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

이렇게 호출해도 2초 뒤에 3가지가 동시에 출력된다. 물론 두번째 코드가 더 간결하고 가독성이 좋다.
Promise.all은 배열을 인자로 받는다. 배열의 원소는 프로미스 객체가 된다. Promise.all은 병렬적으로 배열의 원소에 있는 프로미스를 동시에 실행시킨다. 콜백함수로는 동시에 3가지를 2초후에 출력할 수 없다.

(async function() => {
    const name = await getName();
    const age = await getAge();
    const address = await getAddress();

    console.log(name, age, address);
})();

await 키워드에서 하나의 프로미스가 resolve된 뒤 name에 저장하고 다음 순서로 넘어가기 때문에 6초 뒤에 3가지가 동시에 출력된다.

HTTP, REST API

HTTP(Hypertext Transfer Protocol)

Web에서 서버와 클라이언트 간의 통신규약
클라이언트: 웹 브라우저 등 서버로 요청을 보내는 대상.
서버: 클라이언트가 요청을 보내기 전까지 대응하지 않음.
서버와 클라이언트 사이에는 무수히 많은 요소가 존재.
HTTP는 이런 존재들 사이의 통신 방법을 규정한다.

HTTP 메세지
서버 주소, 요청 메서드, 상태 코드, target path, 헤더 정보, 바디 정보 등이 포함된다.
요청 메시지, 응답 메시지의 모양이 다르다.
HTTP/1.1 메시지는 사람이 읽을 수 있음,HTTP2의 메세지는 사람이 읽을 수 없다.

HTTP 헤더
클라이언트와 서버가 요청 또는 응답으로 부가적인 정보를 전송할 수 있도록 해준다.
HTTP 메시지의 헤더에는 콘텐츠 관련 정보, 인증 관련 정보, 쿠키 정보, 캐시 관련 정보 등 서버와 클라이언트 간 통신 시 필요한 정보를 담는다.
클라이언트 요청 시, 서버 응답 시 모두 헤더에 정보를 담을 수 있다

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

HTTP 요청 메서드
HTTP에서, 클라이언트는 서버로 요청을 보낸다.
요청 시 요청 메서드로 특정 요청에 대한 동작을 정의한다.
GET(가져오기), POST(올리기), PUT(올린 것 업데이트), PATCH(올린 것 업데이트), DELETE, OPTIONS, CONNECT, TRACE 등이 규정됨

REST API

API(Application Programming Interface)는 사용자가 특정 기능을 사용할 수 있도록 제공하는 함수 를 의미한다.REST API는 HTTP의 요청 메서드에 응하는 서버 API와 클라이언트 간 통신의 구조가 지켜야 할 좋은 방법을 명시한 것이다.구체적인 내용으로는 요청 메서드의 의미, URI 설계, 클라이언트의 상태에 대한 동작 등을 정의한다

REST API 요청 메서드
GET - 리소스 정보를 얻음.
POST - 리소스를 생성.
PUT - 리소스를 생성하거나 업데이트.
DELETE - 리소스를 제거

Fetch API

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

기존 XMLHTTPRequest를 대체하는 HTTP 요청 API.
ES6에 추가된 Promise 객체를 리턴하도록 정의되었다.
네트워크 요청 성공 시, Promise는 Response 객체를 resolve 한다.
네트워크 요청 실패 시, Promise는 에러를 reject 한다.

fetch(serverURL)
  .then(response => {
  response.ok //200~299 true, else:false
  response.status //4o4,504 등
  response.statusText //OK,NOT FOUND
  response.url //https://
  response.bodyUsed
})

Response 객체는 결과에 대한 다양한
정보를 담는다.
response.ok: HTTP Status code가 200-299 사이면 true, 그 외 false이다. 요청은 성공했지만 false가 된다.
response.status: HTTP status code를 담는다.
response.statusText: ok/Not Found 등을 담는다.
response.url은 요청한 URL 정보를 담는다.

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

fetch API로 URL을 받고 resp.header로 Response 객체의 헤더 정보를 얻을 수 있다.

fetch(serverURL)
	.then(response => {
		return response.json()
  		//얻어온 정보를 json으로 만드는 프로미스
  		//비동기함수다.
})
	.then(json => {
		console.log('body : ',json)
  		//json을 읽어 출력한다.
  		//바로 .json하면 프로미스를 json으로 읽는 것이 되어서 오류가 발생한다.
})

response.json()메서드로 얻어온 body 정보를 json으로 만드는 프로미스를 반환한다. .then으로 프로미스를 받아온 뒤 resolve 되면 얻어온 body 정보를 읽는다.response.text(), response.blob(), response.formData() 등의 메서드로 다른 형태의 바디를 읽을 수 있다.

fetch(serverURL, {
	method: 'post',
  //get,post,put 등 요청 메서드를 넣는다.
	headers: {
      'Content-Type':
      'application/json;charset=utf-8',
      Authentication: 'mysecret'
    },
  body: JSON.stringify(formData)
})
  .then(response => {
  return response.json()
  //비동기함수다.
})
  .then(json => {
  console.log('POST 요청 결과:', json)
})

fetch(url, options) 로, fetch 메서드
옵션을 넣는다. method 필드로 여러 요청 메서드를
활용한다. headers, body 필드를 활용해 서버에
추가 정보를 보낸다.

profile
뿌링클 치즈맛

0개의 댓글