'$.ajax'에 해당되는 글 1건

  1. 2018.11.07 jquery 의 $.ajax 에 Promise 패턴 이용하기
개발팁2018. 11. 7. 12:40

ajax 는 말그대로, 비동기 통신을 하기 위한, 도구이다.


jquery 에서는 $.ajax 또는 jQuery.ajax 라는 메서드를 통해서, 쉽게 ajax 를 이용할 수 있다.


내부적으로는 XMLHttpRequest 를 이용하고 있으며, 여러가지 편의 기능, option 을 제공하고 있다.


이중에서도, 매번 ajax 로 요청할때, 동일하게 사용하는 option / 처리가 끝나고 결과에(response) 대해 성공/실패/항상 처리해야 할일을 


$.ajaxSetup 에 미리 정의해 놓으면, 코드양도 줄여주고, 간결해지게 된다.



여기서 다룰 내용은, $.ajax 요청이 비동기(asyncronous) 요청이기 때문에, 이를 위해, promise 처리를 하는 방법이다.


기본적으로, $.ajax 요청의 결과를 받는 방법으로 많이 사용되는것이,


complete


success


error


ajax 요청이 완료되고 결과(response) 가 나오면, 우선적으로, complete 에 정의된, 함수 (또는 콜백함수) 가 실행이 된다.


그리고 나서, 결과가 http 오류인지 http 성공(200 ok) 인지에 따라, success / error 에 정의된 함수 (또는 콜백함수) 가 실행이 된다.


이 방식은, 비동기 요청(ajax) 를 하고 나서, 처리결과에 따라, 다음 작업을 진행해야 할때마다, 매번 callback 함수를 사용해야 하는 문제를 발생시킨다. (불편한 코드의 문제...)


다행이도, $.ajax 는 위의 함수(또는 콜백함수) 기능외에 Promise 패턴이 적용되어 있다. (jquery  의 deferred 로 구현됨)



$.ajax({ url : '/post/url', data: 'param, ... } ).then( function(result, status, responseObj) {

성공일때 내용...

}, function (result, status, responseObj) {

실패일때 처리할 내용...

});


위와 같이 코드를 작성할 수 있다, 뒤의 실패일때의 function 부분은 생략도 가능하다.


이 코드는 다시 아래와 같은 형태로 변경이 가능다.


$.ajax({ url : '/post/url', data: 'param, ... } ).done( function(result, status, responseObj) {

성공일때 내용...

}).fail(function (result, status, responseObj) {

실패일때 처리할 내용...

});


then() 은 done(), fail() 로 분리해서 처리할수 있다.

성공/실패 여부와 상관없이 항상 실행해야 할 코드는 always() 에 넣어줄 수 있다.

 $.ajax({ url : '/post/url', data: 'param, ... } ).done( function(result, status, responseObj) {


성공일때 내용...


}).fail(function (result, status, responseObj) {


실패일때 처리할 내용...


}).always(function (result, status, responseObj) {


항상 처리할 내용...


});



done() 이나 fail() 이 먼저 실행되고 난 후에 always 가 실행이 될것이다.



여기서 주의할 점은, $.ajax 의 promise 패턴은 http response 의 성공(200 ok) 이냐 실패냐에 기인한다는 점이다.

이는, 논리적인 성공 실패가 아니라, 물리적인 성공/실패를 의미하는 것이다.




웹서버에서 오류가 났을때, http 오류가 아니라, 적당한 오류 코드 와 오류 메세지를 response 해준다면, 어떨까?


그렇다면, $.ajax 는 이를 성공으로 간주하게 되어, 성공(done) 에서 논리적인 오류인지를 체크해야 한다.




이를 간소화 하기 위해서 아래와 같이 $.ajax 에 또다른 Promise 패턴을 적용한 래퍼함수(Wrapper) 를 만들 수 있다.


jquery 에서는 promise 패턴을 구현하기 위해, $.Deferred 라는 것을 제공하고 있다.


(실제 promise 패턴을 이용하기 위해 Promise 객체가 있지만, IE 에서는 지원하지 않기때문에, 호환성을 위해, $.deferred 를 사용했다.)



성공, 실패에 대해서는, resolve / reject 함수를 제공하며, 결과는 promise() 를 리턴해주면 된다.


$.ajax.promise = function (options) {

    var deferred = $.Deferred();


    $.ajax(

        options

    ).done(function (result, status, responseObj) {

        if (!result.bSuccess)    // failed

        {

            deferred.reject(result, status);

            return;

        }


        //data = JSON.parse(result.sJsonData);

        data = ( result.sJsonData == null || result.sJsonData == "" ) ? null : JSON.parse(result.sJsonData);


        deferred.resolve(result, data);

    }).fail(function (result, status, responseObj) {

        deferred.reject(result, status);

    });


    return deferred.promise();

}



이 코드의 전제는 json 데이터를 받는다는 점이고, result 에 bSuccess 라는 속성이 존재한다는 점이다.


$.ajax 의 래퍼함수인 $.ajax.promise 를 이용하여, 위의 $.ajax promise 이용 예를 다시 호출해보면 아래와 같다.


 $.ajax.promise({ url : '/post/url', data: 'param, ... } ).done( function(result, data) {


성공일때 내용...


}).fail(function (result, status, responseObj) {


실패일때 처리할 내용...


}).always(function (result, status, responseObj) {


항상 처리할 내용...


});



이제, 위 코드의 성공/실패 코드는 물리적인 http 오류외에도, 논리적인 오류에도 대응되는 코드로 변경이 된다.


위 코드는 단일 ajax 코드를 실행하는 방법이고, jquery 에서는 여러개의 promise 패턴을 처리하는 방법으로,


$.when 이라는 함수를 체공한다.



var pr1 =  $.ajax.promise({ url : '/post/url', data: 'param, ... } );

var pr2 =  $.ajax.promise({ url : '/post/url', data: 'param, ... } );

var pr3 =  $.ajax.promise({ url : '/post/url', data: 'param, ... } );


$.when(pr1, pr2, pr3).done(function() {

      모두 성공일때...

});

비동기 메서드이기 때문에, 위의 3줄은 같은 시기에 실행이 되지만, 결과는 제각각 다르게 나올것이다.

하지만, 모든 실행이 끝나고 나서, 처리해야할 내용이 있을때,

done() 함수에 넣어주면 된다.


$.when 도 promise 패턴으로 구현되어 있기 때문에,


done / fail / then 모두 사용가능하다.



Posted by 헝개