在nodejs循环中发出http请求

Posted

技术标签:

【中文标题】在nodejs循环中发出http请求【英文标题】:making http requests in nodejs loop 【发布时间】:2016-08-24 07:25:34 【问题描述】:

发现几乎不可能将循环中的 http 请求的响应捕获为数组。我可以在 console.log 中看到该数组,但是当我将数组传递为 http 服务器的响应时,我得到一个空白数组。我做错了什么,还是有更好的方法来做到这一点?

代码:

router.route('/uprns').post(function(request, response)
  response.setHeader('content-type', 'application/text');

  console.log('first element from the array is '+request.body.UPRNS[0]);
  console.log('Number of items in array is '+request.body.UPRNS.length);

if (request.body.UPRNS.length == 0) 
         response.send( 'no UPRNS in request' );
    

  var output = [];
  var obj = '';

  for( var i = 0; i < request.body.UPRNS.length; i++) 

    obj = request.body.UPRNS[i];

    //Make  HTTP calls to     
    var options = 
      host: 'orbisdigital.azure-api.net',
      path: '/nosecurity/addresses?uprn='+obj // full URL as path
    ;

    callback = function(res)     
      res.on('data', function (chunk) 
        output.push(chunk.toString());
      );

      //the whole response has been recieved
      res.on('end', function () 
        console.log(output);
      );
    

    Https.request(options, callback).end();
  

  response.send(output);

); 

我知道在 for 循环中有很多关于阻塞进程的讨论,但是没有明确的推荐方法来处理循环中的 http 调用。 谢谢你 。

【问题讨论】:

输出数组中元素的顺序很重要吗?他应该遵守http-requests的顺序吗? 顺序在我的情况下并不重要,但也想知道如何实现顺序。 【参考方案1】:

这里是代码。请参阅添加的 cmets 的代码。阅读一些关于使用 node.js 进行异步编程的文章,here's a starter。

router.route( '/uprns' ).post( function ( request, response ) 
    response.setHeader( 'content-type', 'application/text' );
    console.log( 'first element from the array is ' + request.body.UPRNS[ 0 ] ); // your  1st element in  JSON array.

    console.log( 'Number of items in array is ' + request.body.UPRNS.length );
    var output = [];
    var obj = '';

    for ( var i = 0; i < request.body.UPRNS.length; i++ ) 

        obj = request.body.UPRNS[ i ];

        console.log( obj );

        //Make  HTTP calls to

        var options = 
            host: 'orbisdigital.azure-api.net',
            path: '/nosecurity/addresses?uprn=' + obj // full URL as path
        ;

        Https.request( options, callback ).end();

    

    var countResponses = 0;
    // Don't make functions in a loop, so I moved this function down
    // here.
    function callback( res ) 

        res.on( 'data', function ( chunk ) 
            output.push( chunk.toString() );
        );

        // Handles an error
        request.on('error', function(err) 
          console.error(err.stack);
          response.statusCode = 500; // or what ever.
          response.send(500, 'there was an error');
        );

        //the whole response has been recieved
        res.on( 'end', function () 
            console.log( output );
            countResponses++;
            if (countResponses === request.body.UPRNS.length) 

                // Previously this code was executed directly 
                // after the loop finished.  It did not wait for
                // all the responses, so it sent the empty response.
                // However, the other console.log(output) statements
                // were called after this.
                //
                // There is a bug here that if request.body.UPRNS.length
                // is zero, then the user will never get a response.  I 
                // let you fix this up :).
                response.send( output );
            
         );

    

 );

【讨论】:

@stdob:是的,好点,我会补充。此外,当 request.body.UPRNS.length 为零时,请不要问这个人。 太棒了,就像一个魅力。将处理空请求。感谢您的帮助。 添加了一个简单的 if 条件来处理空输入数组。添加到原始代码中。 if (request.body.UPRNS.length == 0) response.send('请求中没有 UPRNS'); 【参考方案2】:

处理这种情况的更好方法是使用 async.js 而不是 for 循环。 https://github.com/caolan/async

【讨论】:

以上是关于在nodejs循环中发出http请求的主要内容,如果未能解决你的问题,请参考以下文章

C# 在 foreach 循环中发出异步 http 请求

如何使用NodeJS连接从请求中提取请求http标头

Nodejs同步HTTP请求

发出发布请求时出现NodeJS CORS错误

如何从Google Cloud Function(Cheerio,Node.js)发出多个http请求

使用 Nodejs 在未来的准确时间发送 HTTP 请求