在内部进行GET请求循环

时间:2015-07-12 12:19:44

标签: javascript ajax node.js

我的代码:

var locations = {"testurl1", "testurl2"}, results = [];
locations.forEach(function(location,index){
   request.get(location,function (error, response, body){
    if (!error && response.statusCode == 200) {
      var jsonResponse = JSON.parse(body);
      results.add(jsonResponse.address);          
    }
   }
})

console.log(results);

由于异步获取请求,结果将打印为空白。我如何才能完成这项工作,以便在结果中包含所有地址?

2 个答案:

答案 0 :(得分:2)

每次回复后,检查是否是最后一次回复。

var locations = {"testurl1", "testurl2"}, results = [];
locations.forEach(function(location,index){
   request.get(location,function (error, response, body){
    if (!error && response.statusCode == 200) {
      var jsonResponse = JSON.parse(body);
      results.add(jsonResponse.address);          

      console.log('Address received: ' + jsonResponse.address);

      if (results.length == locations.length) {
        console.log('All addresses received');
        console.log(results);
      }
    }
   }
})

您可能还希望有一些超时,因此如果花费的时间太长,您可以显示响应。此外,请求可能会失败,在这种情况下,它不会被添加到结果中,因此您可以保留一个单独的计数器来检查它。有点粗糙,但是像这样:

var locations = {"testurl1", "testurl2"}, results = [];
var failedCount = 0;
locations.forEach(function(location,index){
  request.get(location,function (error, response, body){
    if (!error && response.statusCode == 200) {
      var jsonResponse = JSON.parse(body);
      results.add(jsonResponse.address);          

      console.log('Address received: ' + jsonResponse.address);
    } else {
      // Keep a counter if a request fails.
      failedCount++;
    }

    // Success + failed == total
    if (results.length + failedCount == locations.length) {
      console.log('Addresses received. ' + failedCount + ' requests have failed');
      console.log(results);
    }
  });
});

// Set a timer to check if everything is fetched in X seconds.
setTimeout(function(){
  if (results.length + failedCount < locations.length) {
    console.log('10 seconds have passed and responses are still not complete.');
  }
}, 10000);

答案 1 :(得分:1)

也许承诺可以帮助解决这种情况。这是我的解决方案:

'use strict';

var request = require('request');
var Q = require('q');
var defer = Q.defer();
var promise = defer.promise;
var locations = [
  'http://www.google.com', 'http://www.instagram.com'
],
results = [];

locations.forEach(function(location, index) {
  request.get(location, function(error, response, body) {
    if (!error && parseInt(response.statusCode) === 200) {
       results.push(response.statusCode);
    }
    if ((locations.length - 1) === index) {
      defer.resolve();
    }
  });
});

promise.then(function() {
  console.log('RESULTS:', results);
});

我对此进行了测试,并且工作正常。承诺简要解释here