使用node.js异步并需要获取多个URL

时间:2015-08-22 16:18:49

标签: javascript node.js asynchronous

美好的一天 - 我对这个问题进行了很多询问,但找不到适合我情况的好例子。

目标:使用request和async调用多个url(这些url不同,有些是xml,有些是json),能够扩展链接数量,最终结果是将数据传递给视图解析。

代码:

var express = require('express');
var router = express.Router();
var request = require('request');
var parseString = require('xml2js').parseString;
var async = require('async');

var bis;

var url_bis = {
  url: 'https://www.bis.org/list/cbspeeches/index.rss',
  headers: {
    'User-Agent': 'request'
  }
};

function callback_bis(error, response, body) {
  if (!error && response.statusCode == 200) {
    bis = "";
    parseString(body, function (err, result) {
        bis = result;
        bis = bis["rdf:RDF"]["item"];
    });
  }
}

var doj;

var url_doj = {
  url: 'http://www.justice.gov/feeds/opa/justice-news.xml',
  headers: {
    'User-Agent': 'request'
  }
};

function callback_doj (error, response, body) {
  if (!error && response.statusCode == 200) {
    doj = "";
    parseString(body, function (err, result) {
        _doj = result;
        doj = _doj.rss.channel[0].item;

    });
  }
}   

function feed_doj() {
    request(url_doj, callback_doj);
}
function feed_bis() {
    request(url_bis, callback_bis);
}

router.get('/', function(req, res, next) {

async.parallel({
    bis: feed_bis,
    doj: feed_doj

}, function(err, results) {
    console.log(results)
    // how to get the bis/doj response here in results?
});

});

module.exports = router;

3 个答案:

答案 0 :(得分:1)

使用promises和Promise.all()函数

,这非常容易
var request = require('request-promise');

var calls = [
  request({ url: 'http://...', headers: { ... } }),
  request({ url: 'http://...', headers: { ... } }),
  // ...as many more as you want...
];

Promise.all(calls).then(function(results) {
  // do something with results[0]
  // do something with results[1]
});

Promise API在较新版本的JS中是原生的,并且可以在旧的JS引擎中轻松填充,因此它减少了对async等帮助程序库的需求。

此示例并行运行所有请求。 Promise.all()等待它们全部完成,然后为您提供与原始请求匹配的结果数组。还要注意使用request-promise模块,它只是在request模块的顶部,但返回一个promise而不是回调。

答案 1 :(得分:1)

async需要知道你完成每项任务的时间。为此,使用作为回调函数的参数调用任务。您的任务函数feed_dojfeed_bis应该调用回调函数。这也是从任务中获取输出的标准方法 - 不使用全局函数,它被广泛认为是不好的形式。这样做:

function feed_bis(callback) {
  function callback_bis(error, response, body) {
    if (!error && response.statusCode == 200) {
        parseString(body, function (err, result) {
        var bis = result["rdf:RDF"]["item"];
        callback(null, bis);
      });
    }
  }
  request(url_bis, callback_bis);
}

// And same again for doj

一旦为bis和doj调用了callback函数,将使用参数(err, result)调用主回调; errnull,因为您没有做任何事情来处理错误案例,result将是一个名为bisdoj的属性的对象。< / p>

答案 2 :(得分:0)

您可以使用async模块中包含的并行方法完成此操作,只需将所有请求推送到数组中然后实现:https://github.com/caolan/async/blob/master/README.md#parallel它旨在在所有进程结束时执行最终回调。