2013-12-09 15 views
8

voglio coda di richieste multiple asincrona Ajax che utilizzano le specifiche/promessa differita di jQuery:Attendere il completamento dopo molteplici promesse in parallelo utilizzando 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(); 
}); 

Ecco l'fiddle link. Quindi la mia domanda è:

Nel modello in cui step1 e step2 vengono eseguiti in parallelo, il codice non raggiunge l'ultima funzione del gestore. Perché?

+0

dove si effettua la realtà risolvendo la promessa? Se non si attiva il gestore, la richiamata non verrà chiamata ... – Bergi

+0

I differimenti in 'step1()' e 'step2()' non vengono mai risolti. –

+0

Ya questo è vero, anche se è il caso dell'esempio sequenziale precedente? La promessa non è stata risolta e il codice è ancora completo. – crishushu

risposta

0

Non raggiungere la vostra funzione done se gli date un URL che può effettivamente raggiungere (nel caso di jsfiddle, che sarebbe dire /echo/html/: http://jsfiddle.net/LnaPt/2/

In sostanza, non vi resta che fare questo:

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

è necessario risolvere il deferred obj in step1 e step2

Prova questo

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

Grazie. Una domanda alla tua proposta: perché non restituire deferred.promise() nei passaggi. Dov'è la differenza se restituiremmo delle promesse? – crishushu

+0

@crishushu rinvia e promettono entrambi hanno quindi, hanno fatto i metodi. Ma la promessa non ha il metodo di risoluzione. – Daiwei

+0

la mia domanda si riferisce al comportamento del caso sequenziale (step1(). Then (step2) .done (doSomething);). Non fa differenza se restituiamo l'oggetto posticipato o se restituiamo la sua promessa; entrambi eseguiranno doSomething() – crishushu

4

@Daiwei dà una buona risposta.

Un termine comune a cui fare riferimento è https://gist.github.com/sergio-fry/3917217 di sergio-fry.

caso si vuole avere un approccio più dinamico in cui non si conosce in anticipo quanti argomenti si esegue in parallelo, ecco un buon esempio estensione del 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; 
}; 

Vedere la il codice in azione con un esempio dal vivo dinamica:

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

Problemi correlati