본문 바로가기
JavaScript/Ajax

Ajax) 동기와 비동기 차이, Javascript로 비동기처리

by 박채니 2022. 7. 8.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


 

동기와 비동기 차이

동기식
비동기식

사용자가 서버에 요청/서버 응답까지의 시간을 기다리느냐 기다리지 않느냐에 대한 차이가 있는 것을 알 수 있습니다.

 


javascript로 처리하는 비동기식

- 폼 전송은 무조건 동기식 요청!

- 서버는 동기적 처리 / 비동기적 처리를 구분하지 않음

 

 

GET방식

 

helloAjax.jsp

<body>
	<h1>Ajax - js</h1>
	<form name="searchFrm">
		<input type="search" name="search" />
		<button>검색</button>
	</form>
	
	<script>
	let xhr;
	document.searchFrm.addEventListener('submit', (e) => {
		e.preventDefault(); // 폼 제출 방지! 폼전송은 무조건 동기적 통신
		
		// 1. XMLHttpRequest 객체생성
		xhr = new XMLHttpRequest();
		
		// 2. readystate에 대한 change 핸들러 바인딩
		xhr.onreadystatechange = readyStateChangeHandler; 
		
		// 3. open
		xhr.open("GET", "<%= request.getContextPath()%>/js/search?search=" + e.target.search.value);
		
		// 4. send
		xhr.send();
	});
	
	const readyStateChangeHandler = (e) => {
		switch(xhr.readyState) {
		case 0 : console.log('readyState 0 - uninitilized'); break;	// xhr 객체 생성
		case 1 : console.log('readyState 1 - loading'); break;		// send 호출 전
		case 2 : console.log('readyState 2 - loaded'); break;		// send 호출 시
		case 3 : console.log('readyState 3 - interactive'); break;	// 첫 응답 도착 시
		case 4 : console.log('readyState 4 - completed'); break;	// 응답완료
		}
	};
	</script>
</body>
</html>

폼 제출은 무조건 동기적 통신이기 때문에 submit 이벤트를 이용해서 비동기 처리를 할 수 있습니다.

객체 생성 후, readyState에 대한 change 핸들러를 바인딩 처리하였으며 open의 매개인자로 전송방식과 url을 넘겨주었습니다.

readyState는 0 ~ 4까지 나타내며, 순서대로 xhr 객체생성 → send 호출 전 → send 호출 시 → 첫 응답 도착 시 → 응답완료를 나타냅니다.

 

응답 결과 값 확인 (readyState : 4)

searchServlet

@WebServlet("/js/search")
public class SearchServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1. 사용자 입력 값 처리
		String search = request.getParameter("search");
		
		// 2. 업무로직
		
		// 3. 응답처리
		response.setContentType("text/plain; charset=utf-8"); // 텍스트형식으로 전송
		response.getWriter().print("검색어 [" + search + "] 를 입력하셨습니다 :)");
	}
}

 

<form name="searchFrm">
    <input type="search" name="search" />
    <button>검색</button>
</form>
<div class="result"></div>
<script>
let xhr;
document.searchFrm.addEventListener('submit', (e) => {
    e.preventDefault(); // 폼 제출 방지! 폼전송은 무조건 동기적 통신

    // 1. XMLHttpRequest 객체생성
    xhr = new XMLHttpRequest();

    // 2. readystate에 대한 change 핸들러 바인딩
    xhr.onreadystatechange = readyStateChangeHandler; 

    // 3. open
    xhr.open("GET", "<%= request.getContextPath()%>/js/search?search=" + e.target.search.value);

    // 4. send
    xhr.send();
});

const readyStateChangeHandler = (e) => {
    switch(xhr.readyState) {
    case 0 : console.log('readyState 0 - uninitilized'); break;	// xhr 객체 생성
    case 1 : console.log('readyState 1 - loading'); break;		// send 호출 전
    case 2 : console.log('readyState 2 - loaded'); break;		// send 호출 시
    case 3 : console.log('readyState 3 - interactive'); break;	// 첫 응답 도착 시
    case 4 : console.log('readyState 4 - completed');	// 응답완료
            console.log('결과 코드 : ', xhr.status);
            console.log('결과 값 : ', xhr.responseText);
            alert(xhr.responseText);
            document.querySelector(".result").innerHTML = xhr.responseText;
    }
};

xhr의 status 함수와 responseText 함수로 결과 코드, 넘겨준 결과 값을 확인할 수 있습니다.

이를 이용하여 위와 같이 처리해줄 수도 있겠죠.

 


POST 방식

 

helloAjax.jsp

<form name="signupFrm">
    <label for="userId">아이디</label>
    <input type="text" name="userId" id="userId" />
    <br />
    <label for="userPw">비밀번호</label>
    <input type="password" name="userPw" id="userPw" />
    <br />
    <button>등록</button>
</form>

<script>
document.signupFrm.addEventListener('submit', (e) => {
    e.preventDefault();

    // 1. xhr 객체 생성
    xhr = new XMLHttpRequest();

    // 2. 핸들러 바인딩
    xhr.onreadystatechange = readyStateChangeHandler;

    // 3. open
    xhr.open("POST", "<%= request.getContextPath()%>/js/signup");
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

    // 4. send : Post 방식은 send의 인자로 사용자 입력값을 제공
    // 사용자 입력값을 직렬화 시켜 전달
    xhr.send('userId=' + e.target.userId.value + "&userPw=" + e.target.userPw.value);
});
</script>

 

SignupServlet

@WebServlet("/js/signup")
public class SignupServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1. 사용자 입력 값 처리
		String userId = request.getParameter("userId");
		String userPw = request.getParameter("userPw");
		
		// 2. 업무로직
		
		// 3. 응답처리
		response.setContentType("text/html; charset=utf-8");
		response.getWriter().print("<h2> 축하드립니다. " + userId + "님, 성공적으로 회원가입했습니다.<h2>");
	}
}

url 상에 사용자 입력값을 전달했던 GET방식과는 달리 POST방식은 사용자 입력값을 직렬화하여 send()의 매개인자로 전달해준다는 것을 확인할 수 있습니다.

또한 응답결과가 <h2> </h2> 태그이므로 'text/html'으로 보내주었습니다.

 

'JavaScript > Ajax' 카테고리의 다른 글

Ajax) 검색어 자동완성 기능 (Autocomplete)  (0) 2022.07.12
Ajax) text/html 처리  (0) 2022.07.12
Ajax) text/csv 처리  (0) 2022.07.12
Ajax) text/plain 처리  (0) 2022.07.08
Ajax) 정리  (0) 2022.07.08