2016-01-27 1 views
2

J'ai plusieurs requêtes HTTP dans une application nodejs qui renvoie chacune un mot d'une phrase. Les réponses viendront à des moments différents, donc je les enregistre dans un dictionnaire, la clé étant l'index des mots de la phrase d'origine. Le problème est, quand j'accède à l'objet de demande, je reçois seulement le dernier.Obtention d'un objet de requête d'origine lors de plusieurs appels asynchrones dans nodejs-request

var completed_requests = 0; 
sentence = req.query.sentence; 
sentence = "sentence to be translated" 
responses=[]; 
words = sentence.split(" "); 
for(j=0;j<words.length;j++){ 
    var word = words[j]; 
    var data={ 
     word:word 
    }; 
    var options = { 
     url: 'example.com', 
     form:data, 
     index:j 
    }; 
    request.post(options, function(err,httpResponse,body){ 
     options = options; 
     if(!err){ 
      responses.push({options.index: body}); 
      completed_requests+=1; 
      if(completed_requests==words.length){ 
       var a=""; 
       for(var k=0;k<words.length;k++){ 
        a+=responses[k]+" "; 
       } 
       res.render('pages/index', { something: a }); 
      } 
     } 
     else{ 
      //err 
     } 
    }); 
} 

En fait, quand j'accéder à l'objet object.index, l'objet retourné n'est pas celui utilisé pour la demande initiale, mais le dernier (pour une raison quelconque). Comment devrais-je résoudre cela?

+0

Où définir/définissez-vous l'objet .indice? Pourriez-vous poster ce code? – saintedlama

+0

Le options.index est défini ci-dessus comme ceci: 'var options = { url: 'example.com', forme: données, index: j };' – chintogtokh

Répondre

2

Lorsque nous examinons comment le code est évalué par JavaScript en raison de sa nature Async Node.js le problème devient évident:

  1. Pour le premier mot de la boucle for(j=0;j<words.length;j++){ est exécutée.
  2. La valeur de j est affectée à options.index. Pour la boucle exécutez ce options.index a maintenant la valeur 0.
  3. request.post(options, function(err,httpResponse,body){ est exécuté mais le gestionnaire de rappel sera appelé plus tard.
  4. Pour le premier mot, la boucle for(j=0;j<words.length;j++){ est exécutée.
  5. La valeur de j est affectée à options.index. options.index a maintenant la valeur 1.
  6. request.post(options, function(err,httpResponse,body){ est exécuté mais le gestionnaire de rappel sera appelé plus tard.

Le problème devient maintenant évident car aucun nouvel objet options sont créés, mais la valeur de j est affecté à options.index dans chaque course en boucle. Lorsque le premier gestionnaire de rappel est appelé options.index a la valeur words.length - 1.

Pour résoudre le problème, nous allons envelopper créer les options objet dans une fonction executeRequest

var completed_requests = 0; 
sentence = req.query.sentence; 
sentence = "sentence to be translated" 
responses=[]; 
words = sentence.split(" "); 
for(j=0;j<words.length;j++){ 
    var word = words[j]; 
    var data={ 
     word:word 
    }; 

    function executeRequest(url, form, index) { 
     var options = { 
      url: url, 
      form: form, 
      index: index 
      }; 
      request.post(options, function(err,httpResponse,body){ 
       // options = options; Superfluous 
       if(!err){ 
        responses.push({ [index]: body}); 
        completed_requests+=1; 
        if(completed_requests==words.length){ 
         var a=""; 
         for(var k=0;k<words.length;k++){ 
          a+=responses[k]+" "; 
         } 
         res.render('pages/index', { something: a }); 
        } 
       } 
       else{ 
        //err 
       } 
      }); 
    } 

    executeRequest('example.com', data, j); 
} 

Une bonne lecture au sujet de la portée et de levage en JavaScript peut être trouvé ici http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

0

Vous devez utiliser une routine async comme forEach ou map, aussi je vous suggère de lire la nature asynchrone du nœud pour comprendre comment gérer les rappels pour io.

+0

Lorsque vous prenez un regard plus profond sur le code » Nous verrons que la gestion asynchrone est bien faite manuellement. – saintedlama

+0

Ne peut pas dire sans savoir quelles sont les options variables? –

+0

La variable d'options est définie ci-dessus: 'var options = { url: 'example.com', forme: données, index: j };'. La clé d'index est tirée de l'index de boucle for, et le reste sont des paramètres envoyés à la fonction de requête. – chintogtokh