在nodejs-request中的多个异步调用期间获取原始请求对象
Getting original request object during multiple asynchronous calls in nodejs-request
我在一个 nodejs 应用程序中有多个 HTTP 请求,每个 returns 一个句子的一个词。回复会在不同的时间出现,所以我将它们保存在字典中,键是原始句子的单词索引。问题是,当我访问请求对象时,我只得到最后一个。
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
对象时,返回的对象不是用于原始请求的对象,而是最后一个(出于某种原因)。我该如何解决?
您需要使用 async 例程,例如 forEach 或 map,我还建议您阅读节点的异步特性,以帮助理解如何处理 io 的回调。
当我们看一下 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 中范围界定和提升的好书
我在一个 nodejs 应用程序中有多个 HTTP 请求,每个 returns 一个句子的一个词。回复会在不同的时间出现,所以我将它们保存在字典中,键是原始句子的单词索引。问题是,当我访问请求对象时,我只得到最后一个。
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
对象时,返回的对象不是用于原始请求的对象,而是最后一个(出于某种原因)。我该如何解决?
您需要使用 async 例程,例如 forEach 或 map,我还建议您阅读节点的异步特性,以帮助理解如何处理 io 的回调。
当我们看一下 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 中范围界定和提升的好书