Web/HTML, CSS, JavaScript

Javascript - Ajax 여러개 결과 기다렸다가 특정 함수를 실행하는 방법 비교!

JaeHoney 2022. 5. 5. 16:03
반응형

Ajax 결과 대기

기존에는 Ajax로 요청 하나만 보내는 것을 MSA를 도입하면서 4가지 API에 요청해서 결과를 조합하도록 수정해야 하는 상황이 발생했다.

 

관련하여 요즘 많이 사용하는 메소드가 Promise.all()이다. 사내에서 운영중인 서비스는 IE도 고려해야해서 ES6 문법을 사용할 수 없었다.

 

혹시나 싶어서 호환성을 살펴봤는데, 역시나 IE 지원이 안된다.

 

async: false

Ajax 요청은 기본적으로 비동기로 동작한다. Ajax 속성 중에 async를 false로 설정하면  동기 방식으로 동작한다.

$.ajax({
    type: 'get',
    url: API_URL+'/users?query='+search,
    contentType: 'application/json; charset=utf-8',
    async: false, // 동기 처리
    success: function(response){},
    error: function(){}
});

이 방법을 사용하면 Ajax 요청들에 대한 응답을 모두 받은 후에 데이터를 처리하는 것이 가능하다.

 

하지만 호출하는 API들이 연관이 없을 때 async: false로 동기화하면 성능 저하가 발생한다. 왜냐하면 4가지 API를 호출한다고 하면 요청이 선형으로 동작한다.

 

즉, 아래와 같이 동작하게 된다.

  • 1번째 Ajax 요청을 보낸다.
  • 1번째 Ajax 요청에 대한 응답이 도착하면 2번째 Ajax 요청을 보낸다.
  • 2번째 Ajax 요청에 대한 응답이 도착하면 3번째 Ajax 요청을 보낸다.
  • 3번째 Ajax 요청에 대한 응답이 도착하면 4번째 Ajax 요청을 보낸다.

When, done 구문

Jquery의 when, done을 사용하면 요청을 비동기로 수행하면서도 결과는 나중에 받을 수 있다.

 

코드를 살펴보자. 먼저 각 ajax의 결과를 반환받는다.

var ajax1 = $.ajax({
    type: 'get',
    url: API_URL+'/users?query='+search,
    contentType: 'application/json; charset=utf-8',
    async: false, // 동기 처리
    success: function(response){},
    error: function(){}
});

그리고 when문에 각 ajax요청에 대한 결과를 파라미터로 전부 넘기면 해당 ajax 요청들이 전부 결과를 받았을 때 done문을 실행한다.

$j.when(ajax1, ajax2, ajax3, ajax4).done(function(){
    var total = [].concat(users, contacts, mails, histories);
});

 

만약 ajax가 조건문 안에 존재해서 결과 값을 지역변수에 저장할 수 밖에 없다면 미리 선언만 해도 문제가 없다.

var ajax1, ajax2, ajax3, ajax4;

if(flag) {
    ajax1 = $.ajax({
        type: 'get',
        url: API_URL+'/users?query='+search,
        contentType: 'application/json; charset=utf-8',
        async: false, // 동기 처리
        success: function(response){
            users = response;
        },
        error: function(){}
    });
    
    // ajax2 ...
    
    // ajax3 ...
    
    // ajax4 ...
}

$j.when(ajax1, ajax2, ajax3, ajax4).done(function(){
    var total = [].concat(users, contacts, mails, histories);
    console.log(total);
});

 

결과 확인

결과적으로 API를 분리해서 성능적으로 큰 이점을 얻었다.

 

기존에 사용하던 API(PHP CI)의 경우 543밀리초가 소요되는 반면, 새로운 API(Node, Laravel 등)는 50밀리초 안밖으로 밖에 소요되지 않았다.

정말로 비동기적으로 병렬처리가  되었는 지도 확인해야 한다.

확인해보니 원하는 대로 병렬처리도 잘 되었다.

 

해당 방식으로 여러 개의 비동기 요청을 기다렸다가 결과를 받고 작업을 수행할 수 있다.

 


Reference

반응형