我在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
对象时,返回的对象不是用于原始请求的对象,而是最后一个(由于某种原因)。我该如何解决这个问题?
答案 0 :(得分:2)
当我们看看JavaScript如何评估代码时,由于它在node.js中的异步性质,问题变得很明显:
for(j=0;j<words.length;j++){
。j
的值已分配给options.index
。对于循环运行,此options.index
现在具有值0
。request.post(options, function(err,httpResponse,body){
但稍后会调用回调处理程序。for(j=0;j<words.length;j++){
。j
的值已分配给options.index
。 options.index
现在的值为1
。request.post(options, function(err,httpResponse,body){
但稍后会调用回调处理程序。现在问题变得很明显,因为没有创建新的options
对象,但在每次循环运行中j
的值都被分配给options.index
。调用第一个回调处理程序时,options.index
的值为words.length - 1
。
为了解决这个问题,我们将在函数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);
}
可以在http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html
找到关于JavaScript中作用域和提升的好读物答案 1 :(得分:0)
你需要使用async例程,例如forEach或map,我建议你阅读节点的异步性质,以帮助理解如何处理io的回调。