2013-07-11 10 views
7

Ho bisogno di un metodo per recuperare diversi script con un callback. Questo metodo funziona bene:

fetchScripts:function() { 
    var _this=this; 
    $.when(
     $.ajax({ 
      url:_this.url + 'library/script-one.js', 
      type:'get', 
      cache:true 
     }), 
     $.ajax({ 
      url:_this.url + 'library/script-two.js', 
      type:'get', 
      cache:true 
     }), 
     { .... }, 
     $.ajax({ 
      url:_this.url + 'library/script-n.js', 
      type:'get', 
      cache:true 
     }) 
    ).then(function() { 
     console.log('fetch is done'); 

    }) 
}, 

Ma mi piacerebbe di più generalizzare il metodo perché redundany è in aumento. È possibile passare una promessa a $ .when()? Qui di seguito il mio primo tentativo - ma URL è sempre lo stesso, vale a dire 'script-n.js' forse ho perso il punto e si potrebbe illustrare una soluzione più "bellezza"

fetchScripts:function() { 
    this.deferred=new $.Deferred(); 
    this.promise=this.deferred.promise(); 
    var _this=this; 
    $.each([ 
     'script-one.js', 
     'script-two.js', 
     (....), 
     'script-n.js' 
    ],function() { 
     _this.script=this; 
     _this.promise.then(function(){ 
      return $.ajax({ 
       url:_this.url + 'library/' + _this.script, 
       type:'get', 
       cache:true 
      }) 
     }); 
    }); 
    $.when(
     this.promise 
    ).then(function() { 
     console.log('fetch is done'); 

    }); 
    this.deferred.resolve(); 
}, 

risposta

27

Hai ancora bisogno $ .quando . Ma invece, creare un array di Deferreds (o promesse) e poi apply a $ .quando:

fetchScripts:function() { 
    var base = this.url; 
    var defaults = { 
     type:'get', 
     cache:true 
    }; 

    var libraries = [ 
     'library/script-one.js', 
     'library/script-two.js', 
     'library/script-n.js' 
    ]; 

    var deferreds = $.map(libraries, function(current) { 
     var ajaxOptions = $.extend({ url: base + current }, defaults); 
     return $.ajax(ajaxOptions); 
    }); 

    $.when.apply($, deferreds).then(function() { 
     console.log('All done'); 
    }); 
} 

alternativa di estendere le impostazioni predefinite, si potrebbe utilizzare $.ajax(defaults).

+0

Per accedere ai risultati dei valori differita è possibile utilizzare la variabile 'arguments' magia all'interno della funzione anonima passata a' .then'; –

+0

Ho notato che quando si usa then(), se una qualsiasi delle richieste fallisce, si entrerà nella sua funzione nonostante non sia stata completata, mentre con done(), verrà eseguita solo quando l'ultima a essere terminata, non importa se alcuni falliscono. –

4

Prova

fetchScripts: function() { 
    var deferred = new $.Deferred(); 
    var _this=this; 

    var promises = $.map([ 
     'script-one.js', 
     'script-two.js', 
     (....), 
     'script-n.js' 
    ], function(item, idx) { 
     return $.ajax({ 
      url:_this.url + 'library/' + item.script, 
      type:'get', 
      cache:true 
     }) 
    }); 

    $.when.apply($, promises).then(function() { 
     console.log('fetch is done'); 
     deferred.resolve() 
    }); 
    return deferred.promise(); 
} 
+0

Penso che tu intenda "$ .map", non "$ .each". Anche solo 'item', non' item.script' :-) –

+0

@RocketHazmat si, copia incolla errore –

Problemi correlati