async.map 之前的节点 http 请求

Nodes http request before an async.map

在使用 async.map 启动对它们的查询之前,我遇到了从 http 请求接收数组的问题。

我的服务器端控制器代码如下(express 4):

'use strict';
var _ = require('lodash');
var request = require('request');
var asynce = require('async');
exports.index = function (req, res) {
    function cleanip(str) {
        return str.replace("/", "%2F");
    }
    var myUrls = [];
    var IpBlockedForSpam = [];
    var list = ["127.0.0.1/32", "192.168.0.1/32"];
    for (var i in list) {
        myUrls.push("http://localhost:9000/myapi/ip/blockedForSpam/" + cleanip(list[i]));
    }
    asynce.map(myUrls, function (url, callback) {
        request(url, function (error, response, html) {
            var r = JSON.parse(html);
            for (var i in r) {
                IpBlockedForSpam.push(r[i]);
            }
            callback(error, html);
        });
    }, function (err, results) {
        res.jsonp(IpBlockedForSpam);
    });
};

此代码使用静态变量列表。

我想要实现的是能够使用这样的 http 请求填充此变量:

 request("http://localhost:9000/myapi/ip", function(error, response, body) {
        //console.log(body);
        remotelist.push(JSON.parse(body));
});

呼叫 http://localhost:9000/myapi/ip return :

[
"127.0.0.1/32",
"192.168.0.1/32"
]

我尝试了很多都没有结果,因为大多数时候,我的异步方法在我要求的检索列表的 http 调用请求之前启动。

另一件事,是否可以像http://localhost:9000/myapi/*那样不使用url而只使用/myapi/*

在此先感谢您的建议,也许我的方法不对。

再见。

您可以将代码放在 request() 回调中,以便首先获取 list,并且仅在检索到它时才获取 运行 其余代码:

'use strict';
var _ = require('lodash');
var request = require('request');
var asynce = require('async');
exports.index = function (req, res) {
    function cleanip(str) {
        return str.replace("/", "%2F");
    }
    var myUrls = [];
    var IpBlockedForSpam = [];
    var list = ["127.0.0.1/32", "192.168.0.1/32"];
    request("http://localhost:9000/myapi/ip", function(error, response, body) {
        // add the IP address array retrieved from this request
        list = list.concat(JSON.parse(body));
        list.forEach(function(item, i) {
            myUrls.push("http://localhost:9000/myapi/ip/blockedForSpam/" + cleanip(item));
        });
        asynce.map(myUrls, function (url, callback) {
            request(url, function (error, response, html) {
                var r = JSON.parse(html);
                for (var i in r) {
                    IpBlockedForSpam.push(r[i]);
                }
                callback(error, html);
            });
        }, function (err, results) {
            res.jsonp(IpBlockedForSpam);
        });
    });
};

P.S。使用 for (var i in r) 迭代数组不被认为是一个好的做法,因为这是一个 属性 迭代,它会意外地包含数组的任何可枚举属性,而不仅仅是数组项。

我现在明白了,下面是工作代码:

'use strict';
var _ = require('lodash');
var request = require('request');
var asynce = require('async');
exports.index = function(req, res) {
    function cleanip(str) {
        return str.replace("/", "%2F");
    }
    var myUrls = [];
    var IpBlockedForSpam = [];
    //var list = ["127.0.0.1/32", "192.168.0.1/32"];
    var list = [];
    request("http://localhost:9000/myapi/ip", function(error, response, body) {
        list = list.concat(JSON.parse(body));
        list.forEach(function(item, i) {
            myUrls.push("http://localhost:9000/myapi/ip/blockedForSpam/" + cleanip(item));
        });
        asynce.map(myUrls, function(url, callback) {
            request(url, function(error, response, html) {
                var r = JSON.parse(html);
                r.forEach(function(item, i) {
                    IpBlockedForSpam.push(r[i]);
                });
                callback(error, html);
            });
        }, function(err, results) {
            res.jsonp(IpBlockedForSpam);
        });
    });
};

一些括号没有闭合,concact 而不是 concat(它帮助我从现在开始真正理解这种方法):)

最后,是否可以像http://localhost:9000/myapi/*那样不使用url而只使用/myapi/*

谢谢@jfriend00