【问题标题】:Asynchronous GET requests for an unknown # of URLs对未知数量的 URL 的异步 GET 请求
【发布时间】:2015-04-28 05:33:35
【问题描述】:

发出未知数量的异步 GET 请求的最佳解决方案是什么?

例如,您有以下 url,'http://www.example.org/',并且您想向以下路径发出一组异步请求:

[
    'http://www.example.org/A-1.html',
    'http://www.example.org/A-2.html',
    'http://www.example.org/A-3.html',
    '...',
    'http://www.example.org/B-1.html'
    'http://www.example.org/B-2.html'
    '...'
]

等等。如果,比如说,'...C-12.html' 不存在,你会得到一个无效的响应头代码。您将如何进行一组并行请求?

【问题讨论】:

  • 当您收到其中一个请求的错误时,您想做什么?停止所有其他请求?忽略那个错误并继续前进?两个可以帮助你的工具是 promises 和 node.js 的异步库。
  • 并行获取请求使用npmjs.com/package/async并行方法。
  • 是的,我以前使用过这两个库,但很想看到一个最佳且优雅的解决方案。我希望停止对该特定迭代器的请求;即 A-1、A-2、A-3,一旦到达 A-20(未定义),这组请求就会停止,但是,B-Z 仍在处理中。

标签: node.js asynchronous web-scraping


【解决方案1】:
    var request=require('request');
    var vrlList = [
        'http://www.example.org/A-1.html',
        'http://www.example.org/A-2.html',
        'http://www.example.org/A-3.html',
        '...',
        'http://www.example.org/B-1.html'
        'http://www.example.org/B-2.html'
        '...'
    ];
    var outPutData = [];
    forEach(function(url,index){


  request({ method: 'GET', uri: url }, function (error, response, body) { 
       outPutData.push({"url":url,data:body});
    }).on('data', function(data) {

    }).on('error', function(err) {
          console.log(err)
    }).on('response', function(response) { 
       response.on('data', function(data) { 
       })
   })

});

【讨论】:

  • 如果您提前知道请求的数量,这是一个干净的解决方案,但是,在这种情况下,您不知道任何给定子集的每个页面的深度。
【解决方案2】:

我认为这是一项算法任务。

假设您有 A-Z(要处理 26 行)。 你也可以并行实现 15 个线程。

所以你加载了process数组的前15行:A-O; 然后在process 上启动多线程进程。 例如,当B-56 未定义(未定义)时,您只需抛出异常并在process 数组中加载下一行P,同时排除行B

这样您将遍历所有剩余的行P-Z

【讨论】:

  • 是的,这与我正在考虑的相同类型的方法......希望看到这个问题的优雅解决方案。
  • @FarhadGhayour,SO 不是为你做饭的厨房(“希望看到这个问题的优雅解决方案”)!如果您深入了解任何一种语言并为此任务至少完成一个项目会怎样?
  • 我将发布解决方案供其他人查看,并希望学习或改进。更简单的方法是使用 util.inherits(CONSTRUCTOR, EventEmitter) 扩展功能,然后对并行请求使用简单的 pub/sub 方法,但也许更强大的解决方案是使用 Promises 或类似 Highland 的东西。
【解决方案3】:

这是我使用 JQuery 延迟对象想出的。

function getUrls(urls, callback) {
  var result,
    i = 0;
  var g = $.Deferred()
    .done(callback);
  urls.forEach(function(u, i) {
    $.getJSON(u, function(data) {
      // Do whatever processing you need to do here
      if (++i === dcnames.length) {
        g.resolve(result) // invoke the callback with the result
      }
    })
  })
}

Deferred 对象等待解析,直到进行最后一次调用。虽然 forEach 是一个同步(阻塞)过程,但由于 getJSON 本身是异步的,因此循环将并行运行所有请求,并等待它们全部完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多