1. 최초의 통신 : 클라이언트 측 렌더링(Client-Side Rendering, CSR)
- 비동기식
- 파일이 실행될 때, 즉 페이지가 로드될 때,
서버로부터 HTTP 요청을 통해 데이터를 다운로드
- 보통 HTML, CSS, JavaScript 및 기타 정적 자산을 가져오는 것을 의미
- 이 요청은 페이지의 초기 로드에 사용
2. 두 번째 통신 : 서버 측 렌더링(Server-Side Rendering, SSR)
- 페이지가 로드된 후
AJAX(Asynchronous JavaScript and XML)를 사용하여 내부적으로 서버와 통신
- 서버에서 초기 페이지를 렌더링하고 완전한 HTML 문서를 생성, 클라이언트에게 보냄
서버가 HTML 문서를 생성하고 초기 데이터를 채워서 전송하기 때문
→ 클라이언트 측에서 AJAX 요청을 사용하여 데이터를 가져오는 것이 필요하지 않음
ex) 사용자가 버튼을 클릭하거나 어떤 입력
페이지가 새로 고쳐지지 않고도 새로운 데이터를 가져오는 등
3. AJAX(Asynchronous JavaScript and XML) 통신
- 웹 애플리케이션에서 비동기적으로 서버와 데이터를 교환하는 기술
- 페이지를 새로고침하지 않고도 웹 페이지의 내용을 업데이트 → 동적으로 데이터를 로드
- 사용자 경험이 향상되고, 서버의 부하를 줄일 수 있음
- 과정
요청 보내기: JavaScript를 사용하여 클라이언트에서 서버로 HTTP 요청을 보냄
보통 XMLHttpRequest (바닐라 쿼리 객체)객체나 fetch API를 사용하여 생성
$ajax로도 할 수 있음
요청 처리: 서버는 요청을 받아들이고 처리한 후, 클라이언트에 응답을 반환
보통 JSON, XML, HTML 또는 기타 형식의 데이터
응답 처리: 클라이언트는 서버로부터 받은 응답을 처리
필요에 따라 페이지의 일부를 업데이트
이때 자바스크립트를 사용하여 DOM을 조작하거나 데이터를 표시
- async : 함수가 비동기적으로 실행
동기식 false, 비동기식 true
- await : 이 자리를 기억해
걸면 async를 붙여야하는게 문법
함수 내부를 나와서 할일 없을 때 다시 실행
내부의 코드는 동기, 외부는 비동기
동기로 통신을 하면 상황에 따라 다 다르기 때문에 다 될 때까지 기다렸다가 그림을 그려야 함
비동기 통신을 하면 상황에 따라 먼저 된 것 먼저 그리고 그림을 그릴 수 있어서 ux가 좋아짐
4. 부분 리로드
- AJAX통신으로 cer을 적용해야 가능함
5. Promise
- 이벤트 루프에 등록된 것을 반드시 처리하는 것
- 비동기 작업을 수행하고 완료되면 처리할 콜백 함수를 지정하는 객체
- 비동기 작업이 완료되었을 때 해당 작업이 완료된 후에 콜백 함수가 실행
- 주요 메커니즘
비동기 작업을 수행하는 함수는 새로운 프로미스 객체를 생성하여 반환
프로미스 객체 resolve와 reject라는 두 개의 함수를 인자로 받음
비동기 작업이 성공적으로 완료 → resolve 함수를 호출하여 프로미스가 이행(fulfilled) 상태
실패하면 → reject 함수를 호출하여 프로미스가 거부(rejected) 상태
이행 상태에 도달한 프로미스는 .then() 메서드를 사용하여 이후의 처리를 등록
거부 상태에 도달한 프로미스는 .catch() 메서드를 사용하여 오류 처리를 등록
6. 클로저(Closures)
- 함수와 그 함수가 선언될 때의 렉시컬 환경(lexical environment)과의 조합
- 함수가 생성될 당시의 스코프에 있는 변수들에 대한 참조를 유지할 수 있게 해줌
- 함수가 스택에서 팝(pop)되어 실행 컨텍스트가 종료된 후
해당 함수에 의해 참조되는 변수들은 메모리에서 해제되지 않고 접근 가능한 상태로 남게 됨
- 캡처링(capturing) : 클로저가 외부 함수의 변수에 접근
외부 함수의 변수를 내부 함수에서 기억하고 있다는 의미
변수가 메모리에서 제거되더라도 클로저가 해당 변수를 가지고 있기 때문 → 해당 변수에 접근 가능
7. 실습 하기
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <title>Document</title> </head> <body> <h1>그림1</h1> <h1>그림2</h1> <h1>그림3</h1> <div id="box"> </div> <h1>그림4</h1> <h1>그림5</h1> <h1>그림6</h1> <script> async function download() { let response = await fetch("http://localhost:8080/user"); let apiUtil = await response.json(); console.log(apiUtil); $("#box").html(`유저네임 : ${apiUtil.body.username}`); } download(); alert("헤헤"); </script> </body> </html>
package com.example.myserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
package com.example.myserver; import lombok.AllArgsConstructor; import lombok.Data; @AllArgsConstructor @Data public class User { private int id; private String username; private String password; private String email; }
package com.example.myserver; import lombok.AllArgsConstructor; import lombok.Data; @AllArgsConstructor @Data public class ApiUtil<T> { private int status; private String msg; private T body; }
package com.example.myserver; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @CrossOrigin @RestController public class HelloController { @GetMapping("/user") public ApiUtil<?> getUserOne() { try { Thread.sleep(5000); } catch (InterruptedException e) { throw new RuntimeException(e); } User user = new User(1, "ssar", "1234", "ssar@nate.com"); return new ApiUtil<>(200, "성공", user); } }
Share article