-----------------------------------

Acquista i software ArcGIS tramite Studio A&T srl, rivenditore autorizzato dei prodotti Esri.

I migliori software GIS, il miglior supporto tecnico!

I migliori software GIS, il miglior supporto tecnico!
Azienda operante nel settore GIS dal 2001, specializzata nell’utilizzo della tecnologia ArcGIS e aderente ai programmi Esri Italia Business Network ed Esri Partner Network

-----------------------------------



domenica 6 giugno 2010

Deferreds

Javascript non supporta il concetto di threads ma offre la possibilità di eseguire richieste asincrone con l'oggetto XMLHttpRequest e attraverso i ritardi con la funzione setTimeout.

Dojo mette a disposizione una classe chiamata Deferred che aiuta a gestire la complessità degli eventi asincroni astraendola con una interfaccia consistente.

Vediamo un esempio

 var d = new dojo.Deferred(/* Optional cancellation function goes here */);
  
                //aggiungi una funzione di callback
  
                d.addCallback(function(response) {
  
                  console.log("La response e': ", response);
  
                  return response +1;
  
                });
  
                //Aggiungi un'altra callback che viene eseguita dopo la precedente
  
                d.addCallback(function(response) {
  
                  console.log("La response e': ", response);
  
                  return response + 1;
  
                });
  
                d.addErrback(function(response) {
  
                  console.log("C'è un errore: ", response);
  
                  return response;
  
                });
  
                d.callback(100);  

Questo è quello che vedremo in console:


Deferreds consente di concatenare insieme multiple callback e errbacks così da essere eseguite in ordine sequenziale. Inoltre il Deferreds consente di fornire una funzione di annullamento così da eseguire un'operazione di abort in richieste asincrone.

Tutte le chiamate di input/output alla rete restitutiscono un Deferred perchè offre una maggiore flessibilità nella gestione delle chiamate asincrone.

Vediamo un esempio applicato ad una funzione XHR.

 var d = dojo.xhrGet({
  
        url : "/legend.json",
  
        handleAs : "json", 
  
                 load : function(response, ioArgs) {
  
                  return response; // passa al prossimo callback
  
                 },
  
                 error : function(response, ioArgs) {
  
                  return response; //passa al prossimo errback
  
                 }
  
                });
  
                //chiamato una volta che il load è completato
  
                d.addCallback(function(response) {
  
                      console.log("Il response 1 e': ", response);
  
                      //passato al prossimo callback
  
                   return response;
  
                });
  
                d.addCallback(function(response) {
  
                      console.log("Il response 2 e': ", response);
  
                   return response;
  
                });
  
                d.addErrback(function(response) {
  
                      console.log("C'è un errore: ", response);
  
                   return response;
  
                });  

Questo è il risultato in console:




Per annullare un'operazione asincrona 'iniettiamo' un deferred negli eventi load ed error:

 var d = new dojo.Deferred;
  
                     //aggiungi una funzione di callback
  
                     d.addCallback(function(response){
  
                          console.log("Callback 1: ", response);
  
                          return response;
  
                     });
  
                     //Aggiungi un'altra callback che viene eseguita dopo la precedente
  
                     d.addCallback(function(response){
  
                          console.log("Callback 2: ", response);
  
                          return response;
  
                     });
  
                     d.addErrback(function(response){
  
                          console.log("Errback 1: ", response);
  
                          return response;
  
                     });
  
                     d.addErrback(function(response){
  
                          console.log("Errback 2: ", response);
  
                          return response;
  
                     });
  
                     request = dojo.xhrGet({
  
                          url: "/legend.json",
  
                          handleAs: "json",
  
                          timeout: 5000,
  
                          load: function(response, ioArgs){
  
                               console.log("load: ", response);
  
                               d.callback(response, ioArgs);
  
                               return response; // passa al prossimo callback
  
                          },
  
                          error: function(response, ioArgs){
  
                               console.log("error: ", response);
  
                               d.errback(response, ioArgs);
  
                               return response; //passa al prossimo errback
  
                          }
  
                     });  

Se non annulliamo avremo:

se annulliamo con un: request.cancel() avremo



Infine vi segnalo il DeferredList che fa parte del core che facilita la gestione di multipli Deferreds.

Vediamo un esempio pratico con le API Javascript ESRI. Tenete presente che dalla versione 1.4 i task restituiscono un oggetto dojo.Deferred che permette di monitorare lo stato della richiesta e gestire la comunicazione di thread asincroni.

 var mapDeferred = esri.arcgis.utils.createMap(itemInfo, "map", {
  
       mapOptions: {
  
        slider: true
  
       },
  
       bingMapsKey: bingMapsKey,
  
 geometryServiceURL: "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"
  
  });
  
 mapDeferred.addCallback(function(response) {
  
       map = response.map;
  
       dojo.connect(dijit.byId('map'), 'resize', resizeMap);
  
 });
  
 mapDeferred.addErrback(function(error) {
  
      console.log("Map creation failed: ", dojo.toJson(error));
  
 });
  

Il metodo esri.arcgis.utils.createMap che crea una mappa utilizzando informazioni da arcgis.com restituisce un dojo.Deferred con response:
{
map: esri.Map,
itemInfo:{
item: Object,
itemData:Object
}
}

che utilizziamo per aggiungere una funzione di callback per, ad esempio, impostare il resize della mappa.

Nessun commento: