본문 바로가기

02. JavaScript/01. 기본개념, 문법 (ES6)

JavaScript_02. 문법_13_02. Async/Await

※ 본 내용은 해당 교재를 참고하여 공부한 내용과 본인의 생각을 정리한 글입니다.

https://www.yes24.com/Product/Goods/105608999

 

바닐라 자바스크립트 - 예스24

실무 역량까지 한 번에 잡을 수 있는바닐라 자바스크립트 이론서자바스크립트는 이제 브라우저를 넘어 웹 애플리케이션뿐만 아니라 마이크로 컨트롤러까지 점점 사용하는 곳이 늘어나고 있다.

www.yes24.com

 

 

 Async/Await 역시 Promise와 동일한 목적으로 사용한다.

Async는 말 그대로 비동기 실행을 말하며, Await는 비동기를 실행하는데 결과가 올 때까지 기다리겠다는 의미이다.

 

Fetch 자체가 Promise 이기 때문에 다음 예제 코드처럼 서버로부터 응답이 오면 then() 함수를 이용해서 응답받은 결과를 이용한 코드를 작성할 수 있다.

예제 코드

 

console

 

 위에 예제는 서버로 요청을 보내고 응답을 받은 채로 끝이 났지만, 서버로 요청을 보내고 응답을 받은 후 응답받은 결과를 바탕으로 다시 서버로 요청을 보내는 코드를 작성하려면 다음과 같이 코드가 매우 복잡해지고, 가독성이 떨어진다.

 

예제 코드

 

console

 

 비동기 함수를 호출할 때 함수 앞에 await을 정의하면 비동기 함수가 실행되고, 서버로부터 응답을 받을 때까지 대기(await)한 후 결과를 받으면 실행되도록 해준다.

 

<!DOCTYPE html>
<html>

<head>
  <title>Document</title>
</head>

<body>
  <!-- 비동기 함수를 호출할 때 함수 앞에 await을 정의하면 비동기 함수가 실행되고,
         서버로부터 응답을 받을 때까지 대기(await)한 후 결과를 받으면 실행되도록 해줍니다. -->
  <script>
    function myFetch() {
      fetch("https://jsonplaceholder.typicode.com/posts/1")
        .then(response => response.json()) //response 객체 메소드인 json() 사용하여 JSON 데이터 파싱
        .then((result) => {
          console.log(result); //파싱한 데이터 결과값 console.log
        })
    }

    //myFetch();

    function myFetch2() {
      fetch("https://jsonplaceholder.typicode.com/posts/1")
        .then(response => response.json()) //response 객체 메소드인 json() 사용하여 JSON 데이터 파싱
        .then((result) => {
          console.log(result); //파싱한 데이터 결과값 console.log
          let data = result;

          //응답받은 데이터의 title, body 데이터 수정
          data.title = 'foo';
          data.body = 'bar';

          //요청을 다시 보내야해서 fetch 작성
          fetch("https://jsonplaceholder.typicode.com/posts/1", {
            method: 'PUT',
            body: JSON.stringify(data),
            headers: {
              'Content-type': 'application/json; charset=UTF-8'
            }
          })
            .then(response => response.json())
            .then(result => console.log(result))
        });
    }

    //myFetch2();

    async function myFunction() {
      const res1 = await fetch( //await가 붙은 fetch라서 res1이 응답을 받을 때 까지 기다렸다가 실행된다.
        "https://jsonplaceholder.typicode.com/posts/2"
      );
      let res1Json = await res1.json();
      console.log(res1Json);

      res1Json.title = 'foo';
      res1Json.body = 'bar';

      const res2 = await fetch(
        "https://jsonplaceholder.typicode.com/posts/2",
        {
          method: "PUT",
          body: JSON.stringify(res1Json),
          headers: {
            "Content-type": "application/json; charset=UTF-8",
          },
        }
      );
      let res2Json = await res2.json();
      console.log(res2Json);
    }

    myFunction();
  </script>
</body>

</html>

 

console

 

 서버로 요청을 보내고 응답을 보낸 후 응답받은 결과를 바탕으로 다시 서버로 요청을 보내야할 때 사용하면 좋다.

 

 

 

 

위에서 작성한 예제 코드 중에 궁금한 것이 있어서 찾아본 내용이다.

예제 코드

 

다음은 response 객체 메소드 json() 을 사용하여 JSON 데이터를 파싱하는 구문이다.

 

response => response.json()

 

그럼 JSON 데이터를 파싱해주는 밑에 문법을 써도 되지 않을까?

 

response => JSON.parse(response)

 

이것에 대한 차이점을 찾아보니 다음과 같다.

 

 

● response => response.json()

ㆍResponse 객체의 메소드인 json()을 사용한다.
ㆍresponse.json()은 Promise를 반환하며, 비동기적으로 JSON 데이터를 파싱한다.
ㆍJSON 데이터가 파싱된 후에 사용자 정의 로직을 적용할 수 있는 Promise 체이닝을 허용한다.

 

 

● response => JSON.parse(response)

ㆍJSON.parse() 함수를 직접 사용하여 문자열을 파싱한다.
ㆍJSON.parse()는 동기적으로 작동하며, 비동기적인 특성이 없다. 따라서 fetch에서 얻은 response를 직접 파싱하면 해당 작업이 완료될 때까지 블록된다.
ㆍPromise를 직접 반환하지 않으므로 Promise 체이닝을 사용할 수 없다.

 

 

정리하자면 일반적으로 fetch에서 응답을 받으면 json 메소드를 사용한다.

(비동기, 코드 블록 X 등)

 

 

 

위에서 체이닝은 메소드 채이닝을 가리키며 쉽게 설명하면 .then() 처럼 막 뒤에 붙여서 쓰는 것을 의미한다. 

fetch(~).then().then().then()

이런식으로 이어 붙여서 실행

 

 

자바에서는  stream() 메소드를 쓸 때 사용했었다.

학원에서 했던 프로젝트에서 하나를 예시로 가져왔다.

 

public List<ReviewDTO> findByMovieIdOrderByReviewNumDesc(String movieId) {
    List<Review> result = reviewRepository.findByMovieIdOrderByReviewNumDesc(movieId);
    return result.stream().map(review -> entityToDTO(review)).collect(Collectors.toList());
}