Total: Today: Yesterday:
연구소/이것저것 | 2016. 4. 18. 15:12 | Posted by 자수씨

이전 포스팅에서는 너무 무지한 상태에서 쓰다보니 다시 봐도 이해가 안되는 듯 하여 쉬운 예제를 통해 정리해보겠습니다.


기존에 promise 패턴이 아닌 callback 방식의 경우에는 아래와 같이 코딩을 하였습니다.

### js


$.ajax({

  url: "/ServerResource.txt",

  success: successFunction,

  error: errorFunction

});


대부분 함수의 파라미터 객체에 function 을 설정하여 결과에 대한 처리를 했습니다. 이러한 경우 callback 이 중첩되어 소스의 가독성도 떨어질 뿐더러 관리가 안되는 단점이 있었습니다.



jQuery 1.5 버전 이후부터는 아래와 같이 ```done()```, ```fail()```, ```always()``` 를 이용하여 결과에 대한 처리를 지정합니다.

### js


var promise = $.ajax({

  url: "/ServerResource.txt"

});

  

promise.done(successFunction);

promise.fail(errorFunction);

promise.always(alwaysFunction);


```jQuery.ajax()``` 는 ```jQuery XMLhttpRequest(jqXHR)``` 을 반환하기 때문에 아래와 같은 방식으로도 구현이 가능합니다.

### js


$.ajax( "example.php" )    

    .done(function() { alert("success"); })    

    .fail(function() { alert("error"); })    

    .always(function() { alert("complete"); }); 


체인 방식이 아니더라도 jqXHR 객체에 직접 지정도 가능합니다.

### js


var jqxhr = $.ajax( "example.php" )    

    .done(function() { alert("success"); })    

    .fail(function() { alert("error"); })    

    .always(function() { alert("complete"); }); 

     

    // perform some work here ... 

     

    // Set another completion function for the request above

    jqxhr.always(function() { alert("another complete"); });



jQuery 1.8 버전 이후부터는 ```then()``` 함수를 사용하여 Promise 패턴을 적용할 수 있습니다.

```then()``` 의 첫번째 인자는 성공에 대한 액션, 두번째 인자에는 실패에 대한 액션을 지정할 수 있습니다.

### js


$.ajax({url: "/ServerResource.txt"}).then([successFunction1, successFunction2, successFunction3], 

                                          [errorFunction1, errorFunction2]);

 

//same as

 

var jqxhr = $.ajax({

  url: "/ServerResource.txt"

});

  

jqxhr.done(successFunction1);

jqxhr.done(successFunction2);

jqxhr.done(successFunction3);

jqxhr.fail(errorFunction1);

jqxhr.fail(errorFunction2);

### js


var promise = $.ajax({

  url: "/ServerResource.txt"

});

  

promise.then(successFunction, errorFunction);

### js


var promise = $.ajax({

  url: "/ServerResource.txt"

});

 

promise.then(successFunction); //no handler for the fail() event




Deferred 객체를 직접 만들어서 사용할 수 있는데, 그 방법은 아래와 같습니다.


### js


var timer;

$('#result').html('waiting…');

  

var promise = process();

promise.done(function() {

  $('#result').html('done.');

});

promise.progress(function() {

  $('#result').html($('#result').html() + '.');

});

 

function process() {

  var deferred = $.Deferred();

 

  timer = setInterval(function() {

    deferred.notify();

  }, 1000);

   

  setTimeout(function() {

     clearInterval(timer);

     deferred.resolve();

  }, 10000);

   

  return deferred.promise();

}




Promise 에 등록된 callback 들을 Deferred 가 각 상황에 맞게 호출해주는 방식입니다.


```then()``` 함수를 이용하면 아래와 같이 구현할 수 있습니다.

### js


var timer;

 

(function process() {

  $('#result').html('waiting…');

  var deferred = $.Deferred();

     

  timer = setInterval(function() {

    deferred.notify();

  }, 1000);

   

  setTimeout(function() {

     clearInterval(timer);

     deferred.resolve();

  }, 10000);

   

  return deferred.promise();

})().then(function() { $('#result').html('done.'); },

          null,

          function() { $('#result').html($('#result').html() + '.'); });



#h3 References

http://www.htmlgoodies.com/beyond/javascript/making-promises-with-jquery-deferred.html

https://api.jquery.com/category/deferred-object/




연구소/이것저것 | 2016. 4. 18. 14:05 | Posted by 자수씨

20대에는 신기술에 관심이 많아서 이것저것 많이 해보고 실무에 적용도 했었는데, 30대가 되고나니 업무도 많아지고 귀찮음 때문에 신기술에 대해 관심이 점점 떨어져갔습니다.


최근에 다시 신기술에 대해 공부하다보니 너무 많은 것들이 쏟아져 나와있었습니다. 그 중 하나가 promise 패턴인데, 항상 callback 가 진리라 생각하고 불편한 상황에서도 계속 쓰고만 있었습니다.



promise 패턴은 스펙 구현체들을 로드하여 사용할 수 있는데, 최근 가장 많이 쓴는 jQuery 에서도 promise 패턴을 활용할 수 있습니다.


jQuery 에서는 ```jQuery.when(deferreds)``` 로 제공이 되며 API 에 있는 예제를 하나씩 확인해보겠습니다.



아래 예제는 ```jQuery.when()``` 의 파라미터인 ```deferred``` 가 정상적으로 처리되면 ```deferred.then``` 에서 콜백과 같은 처리를 합니다. 기존의 방식과는 달리 콜백이 중첩되지 않는 구조입니다.


### js


$.when( $.ajax( "test.aspx" ) ).then(function( data, textStatus, jqXHR ) {

  alert( jqXHR.status ); // Alerts 200

});



```jQuery.when()``` 의 파라미터가 Deferred 나 Promise 가 아닐 경우에는 done 콜백이 즉시 실행됩니다.

### js


$.when( { testing: 123 } ).done(function( x ) {

  alert( x.testing ); // Alerts "123"

});


파라미터가 없는 경우에도 즉시 실행됩니다.

### js


$.when().then(function( x ) {

  alert( "I fired immediately" );

});




아래는 ```jQuery.Deferred()``` 를 이용한 예제인데, 아직 잘 이해가 되지 않는 부분이 있습니다. Deferred 객체에 대해 학습 후에 다시 정리해야겠습니다.

### js


var d1 = $.Deferred();

var d2 = $.Deferred();

 

$.when( d1, d2 ).done(function ( v1, v2 ) {

    console.log( v1 ); // "Fish"

    console.log( v2 ); // "Pizza"

});

 

d1.resolve( "Fish" );

d2.resolve( "Pizza" );


### js


var d1 = $.Deferred();

var d2 = $.Deferred();

var d3 = $.Deferred();

 

$.when( d1, d2, d3 ).done(function ( v1, v2, v3 ) {

    console.log( v1 ); // v1 is undefined

    console.log( v2 ); // v2 is "abc"

    console.log( v3 ); // v3 is an array [ 1, 2, 3, 4, 5 ]

});

 

d1.resolve();

d2.resolve( "abc" );

d3.resolve( 1, 2, 3, 4, 5 );




#h3 References

https://api.jquery.com/jquery.when/

https://api.jquery.com/category/deferred-object/