简体   繁体   English

node.js:使http调用for循环

[英]node.js : make http calls in for loop

I want to make an http call for each element in an array, and combine all the responses into a single array, like so: 我想对数组中的每个元素进行http调用,并将所有响应组合到一个数组中,如下所示:

result = [] ; i = 0
for item in array
  options = get_options(item)
  request options, (err, res, body)->
    result[i++] = body

// when all calls are done, console.log the 'result' array

I'm looking at the async module, but I'm not really sure how to use it. 我正在查看异步模块,但是我不确定如何使用它。

Try this, should work. 试试这个,应该可以。 You may want to try mapLimit to limit the no of parallel requests or mapSeries to do it in order. 您可能想尝试mapLimit来限制并行请求的数量,或者尝试限制mapSeries来按顺序进行。

var async = require('async');
var request = require('request');
async.map(['url1', 'url2'], function(item, callback){
  request(item, function (error, response, body) {
    callback(error, body);
  });
}, function(err, results){
  console.log(results);
});

for your example I need to see your get_options function. 对于您的示例,我需要查看您的get_options函数。 is it synchronous? 它是同步的吗? if yes you can do this 如果是的话,你可以这样做

var async = require('async');
var request = require('request');
var options;
async.map([item1, item2], function(item, callback){
  options = get_options(item);
  request(options, function (error, response, body) {
    callback(error, body);
  });
}, function(err, results){
  console.log(results);
});

If your get_options is asynchronous and accepts callback do following: 如果您的get_options是异步的并且接受回调,请执行以下操作:

var async = require('async');
var request = require('request');
async.map([item1, item2], function(item, callback){
  get_options(item, function(err, option){
    if(err) {
      callback(err);
    }
    else{
      request(options, function (error, response, body) {
       callback(error, body);
      });
    }
  });
}, function(err, results){
  console.log(results);
});

using async library's map function you can 使用异步库的地图功能,您可以

var makeRequest = function(item, callback){
    var options = get_options(item);
    // handle http errors and getting access to body properly
    http.get(options,res){
        callback(null, res)
    }
}

async.map(['item1','item2','item3'], makeRequest(item, callback), function(err, results){
    //check errors do stuff with results
});

If you're interested in using promises here is an answer for that as well: 如果您有兴趣使用诺言,这里也提供了答案:

var Q = require('q');
var http = require('http');

var httpGet = function(url) {
  var data = "", defer = Q.defer();
  http.get(url, function (res) {
    var content_length = parseInt(res.headers['content-length'], 10);
    var total_downloaded = 0;
    if (res.statusCode !== 200) {
      defer.reject("HTTP Error " + res.statusCode + " for " + url);
      return;
    }
    res.on("error", defer.reject);
    res.on("data", function (chunk) {
      data += chunk;
      total_downloaded += chunk.length;
      var percentage = Math.floor((total_downloaded / content_length) * 100);
      defer.notify(percentage);
    });
    res.on("end", function () { defer.resolve(data); });
  });
  return defer.promise;
}

This uses the Q promises library. 这使用了Q Promise库。 You would use it like this: 您可以这样使用它:

var promise = httpGet("http://example.com/");
promise.then(function (data) {
  // Do something with data.
}, function (reason) {
  // Do something with the error
}, function (progress) {
  // Do something with the progress update (% so far)
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM