在nodejs-request中的多个asynchronous调用期间获取原始请求对象

我有一个nodejs应用程序中的多个HTTP请求,每个返回一个句子的单词。 答案会在不同的时间出现,所以我把它们保存在一本字典中,关键是原文的单词索引。 问题是,当我访问请求对象时,我只能得到最后一个。

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

基本上,当我访问object.index对象时,返回的对象不是用于原始请求的对象,而是最后一个(出于某种原因)。 我应该如何解决这个问题?

当我们看一看代码是如何通过JavaScript进行评估的,因为它在node.js中是asynchronous的,这个问题就变得很明显了:

  1. 对于第一个字,循环for(j=0;j<words.length;j++){被执行。
  2. j的值被分配给options.index 。 对于循环运行这个options.index现在有值0
  3. request.post(options, function(err,httpResponse,body){被执行,但callback处理程序稍后会被调用。
  4. 对于第一个字,循环for(j=0;j<words.length;j++){被执行。
  5. j的值被分配给options.indexoptions.index现在有值1
  6. request.post(options, function(err,httpResponse,body){被执行,但callback处理程序稍后会被调用。

现在问题变得很明显,因为没有创build新的options对象,但是j的值在每个循环运行中都被分配给options.index 。 当第一个callback处理程序被调用时, options.index的值为words.length - 1

为了解决这个问题,我们将在函数executeRequest创build选项对象

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

关于JavaScript的范围和提升的一个很好的阅读可以在这里findhttp://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

您需要使用asynchronous例程,如forEach或map,同时我build议您阅读节点的asynchronous本质,以帮助理解如何处理io的callback。