在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的,这个问题就变得很明显了:
- 对于第一个字,循环
for(j=0;j<words.length;j++){
被执行。 -
j
的值被分配给options.index
。 对于循环运行这个options.index
现在有值0
。 -
request.post(options, function(err,httpResponse,body){
被执行,但callback处理程序稍后会被调用。 - 对于第一个字,循环
for(j=0;j<words.length;j++){
被执行。 -
j
的值被分配给options.index
。options.index
现在有值1
。 -
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。