lang/jquery

$.deferred 비동기 호출 서비스

C/H 2014. 10. 13. 08:30




Query의 디퍼드(Deferreds), 프로미스(Promise), 콜백(Callback)을 사용하면 클라이언트와 서버 애플리케이션에서의 비동기 호출을 적절하게 처리하여 동기식 서비스를 구현할 수 있다. 하지만 개념과 사용 방법이 어려워 개발자들이 이들의 장점을 제대로 이용하지 못하고 있다.



아래 비동기 서비스를 구축에 이용할 수 있는 $.deferred 알기 쉽게 정리한 페이를 참고하세요. Deferred object는 보류(pending) 상태로 시작됩니다. 그리고 실행된 후에 호출될 콜백에 deferred.then(), deferred.always(), deferred.done(), deferred.fail() 중 어느 것이라도 추가할 수 있습니다. deferred.resolve() 또는 deferred.resolveWith() 함수를 호출하면 Deferred는 resolved 상태로 전환되고 그 즉시 doneCallbacks 함수 목록이 실행됩니다. deferred.reject() 또는 deferred.rejectWith() 함수를 호출하면 Deferred는 rejected 상태가 되고 그 즉시 failCallbacks 함수 목록이 실행됩니다. 객체가 resolved 상태가 되거나 rejected 상태가 되면, 그 상태를 유지합니다.



$.deferred 사용

// 이 API를 위한 Promise 객체를 얻는다.
var dataPromise = getData();

// 데이터가 해결됐을 때 호출될 함수를 등록한다.
dataPromise.done(function(data){
  alert("We got data: " + data);
});

// 오류 함수를 등록한다.
dataPromise.fail(function(ex){
  alert("oops, some problem occured: " + ex);
});

// 참고: 원하는 만큼 dataPromise.done(...)을 많이 가질 수 있다.
dataPromise.done(function(data){
  alert("We asked it twice, we get it twice: " + data);
});


$.when, $.deferred 사용

// 가령 getData와 getLocation 둘 다 그들 각자의 Promise를 반환한다면 
var combinedPromise = $.when(getData(), getLocation())

// 함수는 getData와 getLocation이 둘 다 해결됐을 때 호출될 것이다.
combinePromise.done(function(data,location){
  alert("We got data: " + dataResult + " and location: " + location);
}); 


function 으로 deferred 이용하기

function getData(){
  // 1) 사용될 jQuery Deferred 객체를 생성한다.
  var deferred = $.Deferred();
  
  // ---- AJAX 호출 ---- //
  XMLHttpRequest xhr = new XMLHttpRequest();
  xhr.open("GET","data",true);
  
  // 이벤트 핸들러를 등록한다.
  xhr.addEventListener('load',function(){
    if(xhr.status === 200){
      // 3.1) DEFERRED를 해결한다. (모든 done()...을 동작시킬 것이다.)
      deferred.resolve(xhr.response);
    }else{
      // 3.2) DEFERRED를 거부한다. (모든 fail()...을 동작시킬 것이다.)
      deferred.reject("HTTP error: " + xhr.status);
    }
  },false) 
  
  // 작업을 수행한다.
  xhr.send();
  // 참고: jQuery.ajax를 사용할 수 있었고 해야할 수 있었다.
  // 참고: jQuery.ajax는 Promise를 반환하지만 다른 Deferred/Promise를 사용하여 애플리케이션에 의미있는 구문으로 감싸는 것은 언제나 좋은 생각이다.
  // ---- /AJAX 호출 ---- //
  
  // 2) 이 deferred의 promise를 반환한다.
  return deferred.promise();
}


반응형