우리 잠깐 ajax를 한번 생각을 해보자 ajax를 보면 async라는 옵션이 있는데 이를 true로 두면 비동기 수행이고 이를 false로 두면 동기 수행입니다 그럼 간단한 예제를 한번 만들어보자 간단하게 서버 api를 만들어보겠습니다
동기 vs 비동기
1
2
3
4
5
6
7
8
9
10
11
12
13
@GetMapping("/demo")
@ResponseBody
public Map<String , Object> demoHandler(){
Map<String , Object> resultMap = new HashMap<>();
resultMap.put("fruits1" , "apple");
resultMap.put("fruits2" , "melon");
return resultMap;
}
demo 를 호출하게 되면 이는 map 를 return 합니다 그럼 ajax를 작성해보면
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function click(){
$.ajax({
type : "get" ,
url : "/demo",
async : false ,
headers : {
},
success : (data => {
console.log(data);
}) ,
error : ( (request , status , error) => {
console.log(request , status , error)
})
})
console.log("어디가 먼저 호출될까요?")
}
click()
간단한 click 함수를 만든 다음에 async -> 동기식으로 주게 되면
1
2
{fruits1 : ""apple"" , fruits2 :"melon"}
어디가 먼저 호출될까요?
서버와 통신이 이루어지고 난 다음에 바깥에 있는 console 이 호출되는 것을 볼 수 있습니다
이번에는 async 비동기식 -> true로 주게 되면 전혀 반대로
1
2
3
어디가 먼저 호출될까요?
{fruits1 : ""apple"" , fruits2 :"melon"}
이렇게 호출이 됩니다 즉 동기식은 위에 통신이 끝나기 전까지는 blocking 을 하고 있습니다 반대로 비동기식은 순서를 보장하지 않고 먼저 호출할 수 있는 것들부터 호출하게 됩니다
다만 이 ajax를 사용을 하려면 jquery를 js 파일을 구하거나 cdn 을 통해서 사용할 수 있습니다 fetch 가 나오기 이전까지는 순수 자바스크립트로 서버 측과 통신을 하려면 족히 10줄 이상이 되는 자바스크립트를 구현을 했어야 했는데 ajax로는 몇 줄 안되게 서버와 통신을 할 수 있어서 나름 각광받는 js 라이브러리였습니다 다만 ESNext로 오면서 순수 자바 스크립트로 서버와 비동기 통신을 할 수 있는 fetch 가 구현이 되었는데 fetch 이렇게 사용할 수 있습니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
async function fetch_function(){
try{
const response = await fetch('http://localhost:8080/demo' , {
method : "GET" ,
headers : {},
})
const result = await response.json();
console.log(result);
}catch(error){
console.log(error)
}
}
이런 식으로 사용할 수 있습니다 이때 용어를 잘 알아야 하는데 이때 넘어오는 response 데이터를 프라미스 데이터라고 할 수 있습니다 이런 프라미스 객체는 then이라는 표현식으로 사용을 해야 하는데 우리는 지금 쓰이지 않았는데 만약 여기서 then 을 쓰게 되면 이런 모양일 것이다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
async function fetch_function(){
try{
const response = await fetch('http://localhost:8080/demo' , {
method : "GET" ,
headers : {},
}).then(res => {
const status = res.status;
if(status != 200){
alert('서버와의 통신이 실패했습니다')
}else{
return res.json()
}
}).then( res2 => {
console.log('res2' , res2);
})
//const result = await response.json();
//console.log(result);
}catch(error){
console.log(error)
}
}
약간의 기교를 넣어보았는데 첫 번째 then에서 res는 데이터가 바로 넘어오지 않고 http 상태 코드를 포함한 여러 가지 정보가 담겨서 오게 됩니다 우선적으로 status만 분리해서 사용을 하고 200 이면 return 을 줘서 다른 then에서 res2를 최종적으로 값을 받을 수 있습니다 이 결과는 다음과 같습니다
1
res2 -> {fruits1 : ""apple"" , fruits2 :"melon"}