2010-09-22 4 views
1

J'écris du code Javascript/jQuery qui nécessite de faire beaucoup de demandes à diverses API. J'ai rencontré ce problème plusieurs fois et c'est juste un exemple de base d'une instance de celui-ci.Éviter la répétition lors de l'utilisation de fonctions de rappel et de requêtes asynchrones

Le code envoie une requête asynchrone à un serveur et si une condition avec les données renvoyées n'est pas satisfaite, le code effectue une autre demande. La deuxième requête a un rappel qui contient beaucoup de la même logique que son parent. Je sais que j'évite la répétition en appelant le returnFunction dans chaque rappel, mais y a-t-il un moyen d'éviter cela?

var container = []; 

$.getJSON("http://www.url.com/api/?callback=?", 
{ data: "mydata" }, 
function(data) { 
    if(!data.length) { 
     // No results 
    } else { 

     // Put the results into an array 
     $(data).each(function(k, v){ 
      container.push(v.some_data); 
     }); 

     // If the query did not return enough results 
     if(data.length < limit) { 
      var number_missing = limit - data.length; 

      // Get some more results and append to the array 
      myFunctionToGetSomethingElse(number_missing, function(response){ 

       // Add these results to the array 
       $(response).each(function(k, v){ 
        container.push(v.some_data); 
       }); 

       // Do something with this data 
       returnFunction(response); 
      }); 

     } else { 
      // Do something with the result 
      returnFunction(data); 
     } 
    } 
}); 

Comment recommanderiez-vous d'éviter la répétition du code dans les rappels? Est-ce la seule façon possible?

Répondre

1

Il existe une bibliothèque fournissant un "javascript stratifié". Curieusement, il encapsule les appels asynchrones dans un paradigme séquentiel. Retour à la case départ :)

Jetez un oeil à oni labs.

+0

accepté votre réponse parce que vous étiez d'abord. La réponse de tomg a été très utile cependant! On dirait un outil plutôt sympa. – betamax

0

Je n'ai pas de réponse à votre question - comment éliminer la duplication - mais une façon de rendre cela un peu plus propre serait de l'aplatir rapidement. Je pense que vous pourriez envelopper la boucle de chargement de la matrice dans sa propre fonction; Je ne vois pas pourquoi ce serait un problème, mais je ne connais pas javascript assez bien pour le dire en toute confiance.

2
// <script src="http://code.onilabs.com/0.9.1/oni-apollo.js"></script> 
// <script type="text/sjs"> 

// install stratified versions of jquery functions; see below 
require('jquery-binding').install(); 

// Note the extra '$' in $getJSON. This is the 'stratified' version of 
// getJSON. Instead of taking a callback it blocks until the result is 
// available. The browser will stay responsive during that time. 

var data = $.$getJSON("http://www.url.com/api/?callback=?", {data: "mydata"}); 
if (!data.length) { 
 // no results 
} else { 

 $(data).each(function(k, v){ 
    container.push(v.some_data); 
    }); 

 if (data.length < limit) { 
   var number_missing = limit - data.length; 
   // assuming your function 'myFunctionToGetSomethingElse' uses 
   // something like $.$getJSON inside, again you don't need a 
   // callback 
   $(myFunctionToGetSomethingElse(number_missing)).each(
     function(k, v){ 
     container.push(v.some_data); 
     }); 
     } 
} 

// console.log(container); 
// do something with the result. E.g. call returnFunction() or put the 
// code from returnFunction here directly 

Vous pouvez obtenir plus d'informations sur http://onilabs.com/apollo

Questions connexes