简体   繁体   中英

Nodes http request before an async.map

I'm facing issue to receive an array from a http request before using async.map to launch queries on them.

My server side controller code below (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);
    });
};

This code work with var list as static.

What i want to achieive is to be able fill this variable using a http request like this :

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

Calling http://localhost:9000/myapi/ip return :

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

I tried many thing without results because most time, my async method is launched before my required http call request to retrieve list.

Another thing, is it possible to not use url like http://localhost:9000/myapi/* and use only /myapi/*

Thank you in advance for suggestions, maybe i am wrong with this method.

See you.

You can just put the code inside the request() callback so that the list is obtained first and only when it has been retrieved run the rest of the code:

'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);
        });
    });
};

PS it is not considered a good practice to iterate arrays with for (var i in r) because that is a property iteration that will accidentially include any enumerable properties of the array, not just array items.

I got it now, below working code :

'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);
        });
    });
};

Some brackets was not closed and concact instead of concat (it helped me to really understand this approach from now) :)

Last thing, is it possible to not use url like http://localhost:9000/myapi/* and use only /myapi/* ?

Thank you @jfriend00

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM