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

时间:2016-01-27 15:38:14

标签: node.js npm-request

我在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对象时,返回的对象不是用于原始请求的对象,而是最后一个(由于某种原因)。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

当我们看看JavaScript如何评估代码时,由于它在node.js中的异步性质,问题变得很明显:

  1. 对于第一个单词,执行循环for(j=0;j<words.length;j++){
  2. j的值已分配给options.index。对于循环运行,此options.index现在具有值0
  3. 执行
  4. request.post(options, function(err,httpResponse,body){但稍后会调用回调处理程序。
  5. 对于第一个单词,执行循环for(j=0;j<words.length;j++){
  6. j的值已分配给options.indexoptions.index现在的值为1
  7. 执行
  8. request.post(options, function(err,httpResponse,body){但稍后会调用回调处理程序。
  9. 现在问题变得很明显,因为没有创建新的options对象,但在每次循环运行中j的值都被分配给options.index。调用第一个回调处理程序时,options.index的值为words.length - 1

    为了解决这个问题,我们将在函数executeRequest

    中包装创建options对象
    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的回调。