2012-02-10 19 views
5

Ho il seguente codice:concatenazione multiple jQuery Ajax richiede

$.when(loadProjects()) 
    .then(function() { 

     $.when.apply($, buildRequests(projects)) 
     .then(function(data) { 

      $.when.apply($, vcsRequests(buildTypes)) 
      .then(function(data) { 

       $.when.apply($, vcsDetailRequests(vcsRoots)) 
       .then(function(data) { 
        alert('done'); 
       }); 

      }); 

     }); 

    }); 

Ciascuna delle funzioni passate in when.apply() array di ritorno di richieste. Non riesco a eseguire le chiamate buildRequests finché le chiamate da loadProjects() non sono terminate poiché si basano sulle informazioni restituite da tali chiamate. Ogni chiamata dipende dalle informazioni restituite dalla chiamata precedente, quindi devono essere in questo ordine. Devo sapere quando tutte le chiamate sono finite, così posso elaborare i dati restituiti.

C'è un modo più pulito per avvicinarsi a questo?

+0

Sembra che ci siano molte richieste a catena. Vorrei quindi prendere in considerazione la combinazione di tutte le richieste in una sola .... molto più efficiente del concatenamento ... –

+0

Come potrei fare per farlo? Devo chiamare uno dopo l'altro a causa dell'API che sto usando. – JFoulkes

+0

Ho postato la risposta su come ottenere questo risultato perché ai commenti non piace la formattazione del codice :) –

risposta

2

Mi sono imbattuto nello yepnope.js l'altro giorno. Non l'ho ancora provato, ma potrebbe essere utile se stai caricando molto ajax.


Pensandoci sopra mi rendo conto che yepnope.js non è realmente applicabile al tuo caso. Quello che prenderei in considerazione nel tuo caso è di avere loadProjects() e restituire una singola promessa applicando internamente when() in ogni funzione. mettendo anche pipe() da usare potrebbe portare a qualcosa di simile

loadProjects().pipe(buildRequests).pipe(vcsRequests).pipe(vcsDetailRequests); 

Esempio buildRequests():

function buildRequests(projects){ 
    // Do something using projects 
    // ... 

    var requestsPromise = ...; // Finally get ajax promise for requests 
    return requestPromise; 
} 

Il risultato della requestPromise sarà poi passato alla funzione successiva in filodiffusione una volta che è stato risolto/respinta.


Dalla documentazione sulla pipe():

// Example: Chain tasks: 

var request = $.ajax(url, { dataType: "json" }), 
    chained = request.pipe(function(data) { 
     return $.ajax(url2, { data: { user: data.userId } }); 
    }); 

chained.done(function(data) { 
    // data retrieved from url2 as provided by the first request 
}); 
+0

Avete esempi/collegamenti su come fare questo? Sono nuovo di tutto il materiale deffered/promise – JFoulkes

+0

Aggiunto un esempio di una delle funzioni. Gli altri sarebbero simili. Vedi il link incluso in ['.pipe()'] (http://api.jquery.com/deferred.pipe/) per ulteriori informazioni su come funziona. – Supr

+0

Vedo come la pipa sarà d'aiuto, l'unico problema che ho ora è far funzionare questo con un numero dinamico di richieste che ogni funzione restituisce ... – JFoulkes

1

.... risposta secondo il mio commento sul post originale:

Sembra si hanno molte richieste a catena. Vorrei quindi prendere in considerazione che unisce tutte le richieste in sola .... molto più efficiente di concatenamento ...

Beh, qualcosa di simile:

PHP: 
$projects = YourAPI::loadProjects(); 
$builds = YourAPI::getBuilds($projects); 
$vcs = YourAPI::getVCS($builds); 
$details = YourAPI::getVCSDetails($vcs); 

// for example 
return json_encode($details); 

// OR, if you need all the data 
$results = array( 
    "projects" => $projects, 
    "builds" => $builds, 
    "vsc" => $vcs, 
    "details" => $details 
); 
return json_encode($results); 

In questo modo, si ha synhronization inerente tra chiamate e meno HTTP trafiic;)

+0

Non ho intenzione di utilizzare nulla oltre a jook aviator – JFoulkes

+0

, ma quelle richieste di ajax chiamano alcuni script lato server, che si tratti di PHP o di qualsiasi altra lingua, non è vero? –

+0

Sono richieste ajax a un'API che non ho il controllo su – JFoulkes

1

catena dipendenza delle richieste AJAX: È possibile concatenare più richiesta AJAX - per esempio, in prima convocazione recupera i dettagli utente di un utente, e dobbiamo passare quel valore al secondo script. Ricorda che $.then() restituisce una nuova promessa, che può essere successivamente passata allo $.done() o anche a un altro metodo $.then().

var a1 = $.ajax({ 
      url: '/first/request/url', 
      dataType: 'json' 
     }), 
    a2 = a1.then(function(data) { 
      // .then() returns a new promise 
      return $.ajax({ 
       url: '/second/request/url', 
       dataType: 'json', 
       data: data.userId 
      }); 
     }); 

a2.done(function(data) { 
    console.log(data); 
});