2013-07-11 22 views
7

Ich brauche eine Methode, um verschiedene Skripte mit einem Rückruf zu holen. Diese Methode funktioniert ok:

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'); 

    }) 
}, 

aber ich möchte die Methode mehr verallgemeinern, weil Redundanz steigt. Ist es möglich, ein Versprechen an $ .when() zu übergeben? Below mein erster Versuch - aber url ist immer das gleiche, das heißt ‚Skript-n.js‘ Vielleicht habe ich den Punkt und man konnte eine „Schönheit“ Lösung

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(); 
}, 

Antwort

27

Sie müssen noch $ .when illustrieren . Aber stattdessen erstellen eine Reihe von Deferreds (oder Versprechen) und dann apply auf $ .when:

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'); 
    }); 
} 

Alternativ die Standardeinstellungen zu erstrecken, die Sie gerade $.ajax(defaults) nutzen könnten.

+0

Um die Ergebnisse der latenten Werte greifen Sie auf die 'arguments' magische Variable innerhalb der anonymen Funktion' .then' geben können; –

+0

Ich habe festgestellt, dass bei der Verwendung von then(), wenn eine der Anfragen fehlschlägt, Sie ihre Funktion eingeben, obwohl sie nicht erledigt sind, während sie mit done() nur ausgeführt wird, wenn die letzte beendet ist. egal ob einige scheitern. –

4

Versuchen

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

Ich denke du meinst '$ .map', nicht' $ .each'. Auch nur 'item', nicht' item.script' :-) –

+0

@RocketHazmat ja, kopiere einfügen Fehler –