在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 中的异步性质,问题变得很明显:

  1. 对于第一个单词,循环 for(j=0;j<words.length;j++){ 被执行。
  2. j 的值赋给了 options.index。对于循环 运行,此 options.index 现在的值为 0.
  3. request.post(options, function(err,httpResponse,body){ 已执行,但稍后将调用回调处理程序。
  4. 对于第一个单词,循环 for(j=0;j<words.length;j++){ 被执行。
  5. j 的值赋给了 options.indexoptions.index 现在的值为 1.
  6. 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 中范围界定和提升的好书