2012-02-10 18 views
5

Tengo el siguiente código:encadenamiento múltiple jQuery Ajax pide

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

      }); 

     }); 

    }); 

Cada una de las funciones pasaron a when.apply (matrices) de retorno de las solicitudes. No puedo realizar las llamadas buildRequests hasta que las llamadas desde loadProjects() hayan finalizado ya que dependen de la información devuelta por esas llamadas. Cada llamada depende de la información devuelta por la llamada anterior, por lo que deben estar en este orden. Necesito saber cuándo terminaron todas las llamadas para poder procesar los datos devueltos.

¿Hay alguna manera más clara de abordar esto?

+0

Parece que tienes muchas solicitudes para encadenar. Entonces consideraría combinar todas las solicitudes en una sola ... mucho más eficiente que encadenar ... –

+0

¿Cómo podría hacer eso? Tengo que llamar uno después del otro debido a la API que estoy usando. – JFoulkes

+0

Publiqué la respuesta sobre cómo lograr esto porque a los comentarios realmente no les gusta el formato del código :) –

Respuesta

2

Me encontré con yepnope.js el otro día. Todavía no lo he probado, pero podría ser útil si estás cargando mucho ajax.


En realidad pensando que esto me hace más consciente de que yepnope.js no es realmente aplicable a su caso. Lo que consideraría en su caso es que loadProjects() y demás devuelvan una sola promesa aplicando when() internamente en cada función. También poner pipe() a utilizar podría conducir a algo así como

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

Muestra buildRequests():

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

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

El resultado de la requestPromise se pasará entonces a la siguiente función entubada, una vez que se resuelva/rechazado.


A partir de los documentos en 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

¿Tiene muestras/enlaces sobre cómo hacer esto? Soy nuevo en toda la materia diferida/promesa – JFoulkes

+0

Se ha agregado una muestra de una de las funciones. Los otros serían similares. Vea el enlace incluido a ['.pipe()'] (http://api.jquery.com/deferred.pipe/) para más información sobre cómo funciona. – Supr

+0

Veo cómo la pipa ayudará, el único problema que tengo ahora es hacer que esto funcione con un número dinámico de solicitudes que cada función devuelve ... – JFoulkes

1

.... respuesta de acuerdo con mi comentario en el post original:

Parece que tiene gran cantidad de peticiones a la cadena. Yo entonces considerar combinando todas las solicitudes en el solo .... mucho más eficiente que el encadenamiento de ...

Bueno, algo como esto:

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

De esta manera, usted tiene synhronization inherente entre llamadas AND menos trafiic HTTP;)

+0

No tengo intención de usar nada aparte de javascript – JFoulkes

+0

oook, pero esas solicitudes ajax llaman a algunos scripts del lado del servidor, ya sea PHP o cualquier otro idioma, ¿no es así? –

+0

Son solicitudes ajax a una API sobre la que no tengo control – JFoulkes

1

Cadena de dependencia de las solicitudes AJAX: Puede encadenar varias solicitudes AJAX; por ejemplo, la primera llamada recupera los detalles del usuario de un usuario, y necesitamos pasar ese valor a la segunda secuencia de comandos. Recuerde que $.then() devuelve una nueva promesa, que puede pasarse posteriormente al $.done() o incluso a otro $.then() método.

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