NodeJS Needle进程数组的异步请求将url与statusCode匹配

时间:2017-03-03 03:45:33

标签: javascript node.js asynchronous bluebird needle.js

目标:

给定一系列URL,我需要发送一个请求并获取每个请求的statusCode。最后,我需要将该statusCode与对象数组中的请求URL进行匹配,然后可以将这些对象返回到页面。

喜欢这样:

checkList: [
    {
      name: "Google",
      url: "https://www.google.com"
    },
    {
      name: "Microsoft",
      url: "https://www.microsoft.com"
    },
    {
      name: "Github",
      url: "https://www.github.com"
    }
  ]

对于列表中的每个URL,我只需要发出一个http请求并获取状态代码(例如:200)并将其与请求路径匹配。所以最终输出应该是这样的......

results: [
    {
      name: "Google",
      url: "https://www.google.com",
      status: 200
    },
    {
      name: "Microsoft",
      url: "https://www.microsoft.com",
      status: 200
    },
    {
      name: "Github",
      url: "https://www.github.com",
      status: 200
    }
  ]

我目前正在使用BluebirdJSNeedle来处理异步调用以获取响应代码。

问题在于我无法找到将请求网址与响应匹配的方法。由于每个结果都会在不同的时间(按预期)返回,并且Needle响应不包含请求网址,因此我无法说出类似..." https://google.com响应为200& #34 ;.我只能得到一个响应代码列表。

我对高级JS相对较新,所以也许有一种方法可以覆盖回调/承诺,这可以让我在整个过程中传递请求URL,但我不知道如何。

这是我目前使用的代码的要点,基于我在其他地方找到的演示/摘要... https://gist.github.com/sgelliott/13840b6f2f9d2ab481fcded6dc4a9188

代码也包含在下面的内容中......

var needle = require('needle');
var Promise = require("bluebird");
Promise.promisifyAll(needle);

var allPaths = ["https://google.com", "https://microsoft.com", "https://github.com"];
var current = Promise.resolve();

Promise.map(allPaths, function(path) {
    current = current.then(function() {
        console.log("path: " + path); // path shows up here correctly - it's available
        return needle.getAsync(path, options);
    });
    return current;
}).map(function(resp, body) {
    return {
        path: "path goes here",
        status: resp.statusCode
    };
}).then(function(results) {
    console.log("results: " + JSON.stringify(results)); // this outputs 'resulst' : [{"path":"path goes here","status":200},{"path":"path goes here","status":302},{"path":"path goes here","status":200}]
    return renderResults(results); //this simply sets 'statusResults' to 'results' for the next res.send to use - will refine once I solve the path matching issue
}).then(function() {
    console.log('All Needle requests are processed!');
    res.send(statusResults); //
}).catch(function(e) {
    console.log(e);
});

如果这是其他内容的重复,我道歉。经过大量研究后,我无法找到它。如果解决方案是使用Needle以外的东西,那就完全没问题了。我更喜欢坚持使用Bluebird。提前谢谢!

1 个答案:

答案 0 :(得分:0)

我自己已经解决了这个问题,我希望这个解决方案可以用于其他人。这是使用.bind

工作的更新代码
module.exports.gethealth = function (req, res) {
  var statusResults = [];
  var resultCount = 0;
  var allPaths = [];
  for (var item in config.checkList) {
    allPaths[item] = config.checkList[item].url;
  }

  var options = {connection: 'keep-alive'};

  Promise.map(allPaths, function (path) {
    console.log("path: " + path);

    return needle.getAsync(path, options)
      .bind(this, path)
      .then(function (resp, body) {
        statusResults[resultCount] = {path:path, status:resp.statusCode};
        resultCount++;
      });
  }).then(function () {
    res.send(statusResults);
  });

};

如果您有任何后续问题,请与我们联系。