Async parallel requests are running sequentially

前端 未结 3 1687
渐次进展
渐次进展 2020-12-29 00:27

I am running a server using Node.js and need to request data from another server that I am running (localhost:3001). I need to make many requests (~200) to the

相关标签:
3条回答
  • 2020-12-29 00:48

    Try this:

    var async = require("async");
    var request = require("request");
    var show_file = function (file_number,cb) {
        //..Sync ops
         var file_index = Math.round(Math.random() * 495) + 1;
         var pinnacle_file_index = 'http://localhost:3001/generate?file='+file_index.toString();
        //request instance from Request npm Module
        //..Async op --> this should make async.each asynchronous
        request(pinnacle_file_index, function (error, response, body) {
           if(error)
               return cb(error);
           var object_key = "file_" + file_number.toString();
          pinnacle_data[object_key] = JSON.parse(body);
          return cb();
        });
    };
    
    async.each(
      lookup_list, 
      show_file,
      function (err) {
        if(err){
           console.log("Error",err);
        }else{
           console.log("Its ok");
           console.log(pinnacle_data);
       }
    });
    
    0 讨论(0)
  • 2020-12-29 00:59

    As you have discovered, async.parallel() can only parallelize operations that are themselves asynchronous. If the operations are synchronous, then because of the single threaded nature of node.js, the operations will run one after another, not in parallel. But, if the operations are themselves asynchronous, then async.parallel() (or other async methods) will start them all at once and coordinate the results for you.

    Here's a general idea using async.map(). I used async.map() because the idea there is that it takes an array as input and produces an array of results in the same order as the original, but runs all the requests in parallel which seems to line up with what you want:

    var async = require("async");
    var request = require("request");
    
    // create list of URLs
    var lookup_list = [];
    for (var i = 0; i < 20; i++) {
        var index = Math.round(Math.random() * 495) + 1;
        var url = 'http://localhost:3001/generate?file=' + index;
        lookup_list.push(url);
    }
    
    async.map(lookup_list, function(url, callback) {
        // iterator function
        request(url, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var body = JSON.parse(body);
                // do any further processing of the data here
                callback(null, body);
            } else {
                callback(error || response.statusCode);
            }
        });
    }, function(err, results) {
        // completion function
        if (!err) {
            // process all results in the array here
            console.log(results);
            for (var i = 0; i < results.length; i++) {
                // do something with results[i]
            }
        } else {
            // handle error here
        }
    });
    

    And, here's a version using Bluebird promises and somewhat similarly using Promise.map() to iterate the initial array:

    var Promise = require("bluebird");
    var request = Promise.promisifyAll(require("request"), {multiArgs: true});
    
    // create list of URLs
    var lookup_list = [];
    for (var i = 0; i < 20; i++) {
        var index = Math.round(Math.random() * 495) + 1;
        var url = 'http://localhost:3001/generate?file=' + index;
        lookup_list.push(url);
    }
    
    Promise.map(lookup_list, function(url) {
        return request.getAsync(url).spread(function(response, body) {
            if response.statusCode !== 200) {
                throw response.statusCode;
            }
            return JSON.parse(body);
        });
    }).then(function(results) {
        console.log(results);
        for (var i = 0; i < results.length; i++) {
            // process results[i] here
        }
    }, function(err) {
        // process error here
    });
    
    0 讨论(0)
  • 2020-12-29 00:59

    Sounds like you're just trying to download a bunch of URLs in parallel. This will do that:

    var request = require('request');
    var async = require('async');
    
    var urls = ['http://microsoft.com', 'http://yahoo.com', 'http://google.com', 'http://amazon.com'];
    
    var loaders = urls.map( function(url) {
      return function(callback) {
            request(url, callback);
      }
    });
    
    async.parallel(loaders, function(err, results) {
            if (err) throw(err); // ... handle appropriately
            // results will be an array of the results, in 
            // the same order as 'urls', even thought the operation
            // was done in parallel
            console.log(results.length); // == urls.length
    });
    

    or even simpler, using async.map:

    var request = require('request');
    var async = require('async');
    
    var urls = ['http://microsoft.com', 'http://yahoo.com', 'http://google.com', 'http://amazon.com'];
    
    async.map(urls, request, function(err, results) {
            if (err) throw(err);          // handle error 
            console.log(results.length);  // == urls.length
    });
    
    0 讨论(0)
提交回复
热议问题