2013-12-09 10 views
8

chcę stać w kolejce wiele żądań asynchronicznych ajax pomocą odroczony wdrożenia/obietnica jQuery:poczekać na zakończenie po wielokrotnych obietnic równolegle z wykorzystaniem jQuery

function doSomething() { 
    console.log('doSomething')}; 

function makeMultiAjaxRequests1() { 
    console.log('makeMultiAjaxRequests1')}; 

function makeMultiAjaxRequests2() { 
    console.log('makeMultiAjaxRequests2')}; 

var step1 = function() { 
    var promise = new $.Deferred().promise(); 
    makeMultiAjaxRequests1(); 
    return promise; } 

var step2 = function() { 
    var promise = new $.Deferred().promise(); 
    makeMultiAjaxRequests2(); 
    return promise; } 

step1() 
    .then(step2()) 
    .done(doSomething()); 

$.when(step1(), 
     step2()) 
    .done(function() { 
    doSomething(); 
}); 

Oto fiddle link. Moje pytanie brzmi:

W schemacie, w którym krok 1 i krok 2 są wykonywane równolegle, kod nie osiąga ostatniej funkcji obsługi. Czemu?

+0

Gdzie są rzeczywiście rozwiązywania obietnicę? Jeśli nie wyzwolisz procedury obsługi, wywołanie zwrotne nie zostanie wywołane ... – Bergi

+0

Odroczone wartości w "krokach 1()" i "krokach 2()" nigdy nie zostaną rozwiązane. –

+0

To prawda, ale co jest w poprzednim przykładzie sekwencyjnym? Obietnica nie została rozwiązana, a kod nadal się kończy. – crishushu

Odpowiedz

0

To nie osiągnie swoją funkcję done jeśli dać mu adres URL może rzeczywiście osiągnąć (w przypadku jsfiddle, że byłoby powiedzieć /echo/html/: http://jsfiddle.net/LnaPt/2/

Zasadniczo, po prostu trzeba to zrobić:

var promise = $.ajax({ 
    type: "GET", 
    url: "/echo/html/", //<-- instead of google  
}).promise(); 
6

trzeba rozwiązać deferred obj w kroku 1 i STEP2

Spróbuj

function doSomething() { 
    console.log('doSomething')}; 

function makeMultiAjaxRequests1(deferred) { 
    console.log('makeMultiAjaxRequests1') 
    deferred.resolve()}; 

function makeMultiAjaxRequests2(deferred) { 
    console.log('makeMultiAjaxRequests2') 
    deferred.resolve()}; 

var step1 = function() { 
    var deferred = new $.Deferred(); 
    makeMultiAjaxRequests1(deferred); 
    return deferred; } 

var step2 = function() { 
    var deferred = new $.Deferred(); 
    makeMultiAjaxRequests2(deferred); 
    return deferred; } 

step1().then(step2).done(doSomething); 

$.when(step1(), step2()).done(function() { 
    doSomething(); 
}); 
+1

Dzięki. Jedno pytanie do twojej propozycji: dlaczego nie powracać odroczone.promise() w krokach. Gdzie jest różnica, jeśli zwrócimy obietnice? – crishushu

+0

@crishush odroczyć i obietnicy obie mają wtedy, gotowe metody. Ale obietnica nie ma metody rozwiązania. – Daiwei

+0

moje pytanie dotyczy zachowania sekwencji sekwencyjnej (step1(). Then then (step2) .done (doSomething);). Nie ma znaczenia, czy zwrócimy obiekt odroczony, czy też zwrócimy jego obietnicę; oba wykonają doSomething() – crishushu

4

@Daiwei daje dobrą odpowiedź.

Powszechnie obowiązującym określeniem jest https://gist.github.com/sergio-fry/3917217 autorstwa sergio-fry.

Jeżeli chcesz mieć bardziej dynamicznego podejścia, w którym nie wiem ile wcześniej argumenty używasz równolegle, jest tu dobrym przykładem rozszerzenie jQuery (1.10+):

$.whenAll = function (deferreds) { 
    function isPromise(fn) { 
     return fn && typeof fn.then === 'function' && 
      String($.Deferred().then) === String(fn.then); 
    } 
    var d = $.Deferred(), 
     keys = Object.keys(deferreds), 
     args = keys.map(function (k) { 
      return $.Deferred(function (d) { 
       var fn = deferreds[k]; 

       (isPromise(fn) ? fn : $.Deferred(fn)) 
        .done(d.resolve) 
        .fail(function (err) { d.reject(err, k); }) 
       ; 
      }); 
     }); 

    $.when.apply(this, args) 
     .done(function() { 
      var resObj = {}, 
       resArgs = Array.prototype.slice.call(arguments); 
      resArgs.forEach(function (v, i) { resObj[keys[i]] = v; }); 
      d.resolve(resObj); 
     }) 
     .fail(d.reject); 

    return d; 
}; 

Zobacz Kod w akcji z dynamicznym przykład żywej:

http://jsbin.com/nuxuciwabu/edit?js,console

Powiązane problemy