2013-07-11 14 views
7

Potrzebuję metody pobierania różnych skryptów z wywołaniem zwrotnym. Ta metoda działa 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'); 

    }) 
}, 

Ale chciałbym bardziej uogólnić metodę ponieważ redundany wzrasta. Czy można przekazać obietnicę $ .when()? Poniżej moja pierwsza próba - ale url jest zawsze taka sama, czyli „Script-n.js” Może brakowało mi punkt i można zilustrować więcej rozwiązanie „Beauty”

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

Odpowiedz

27

trzeba jeszcze $ .Przy . Ale zamiast tego utworzyć tablicę Deferreds (lub obietnic), a następnie apply to do $ .Przy:

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

Alternatywnie powiększenia ustawienia domyślne, można po prostu użyć $.ajax(defaults).

+0

Aby uzyskać dostęp do wyników odroczonego wartości można użyć 'arguments' magiczną zmienną wewnątrz anonimowej funkcji przekazany do' .then'; –

+0

Zauważyłem, że jeśli używasz then(), jeśli którekolwiek z żądań się nie powiedzie, wejdziesz w jego funkcję, mimo że nie jest ono gotowe, podczas gdy done(), zostanie wykonane dopiero po zakończeniu ostatniego do wykonania, nie ważne, czy niektóre zawiodą. –

4

Spróbuj

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

Myślę, że masz na myśli '$ .map', a nie' $ .each'. Również po prostu 'item', a nie' item.script' :-) –

+0

@RocketHazmat yes, copy paste error –

Powiązane problemy