【问题标题】:Nodes http request before an async.mapasync.map 之前的节点 http 请求
【发布时间】:2015-09-10 23:13:12
【问题描述】:

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

我的服务器端控制器代码如下(表达 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);
    });
};

此代码使用 var list 作为静态代码。

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

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

调用http://localhost:9000/myapi/ip返回:

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

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

另外,是否可以不使用http://localhost:9000/myapi/* 之类的网址而只使用/myapi/*

提前感谢您的建议,也许我对这种方法有误。

再见。

【问题讨论】:

    标签: javascript node.js asynchronous express httprequest


    【解决方案1】:

    您可以将代码放在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);
            });
        });
    };
    

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

    【讨论】:

    • 感谢您的建议,我尝试使用此代码,但出现此错误:asynce.map(myUrls, function (url, callback) { ^^^^^^ SyntaxError: Unexpected identifier
    • @Widy - 我修复了代码中的几个语法错误。您不应该发布属于 cmets 的答案。答案应该只是答案。如果您需要发布的内容超出评论的范围,您可以随时使用问题中的“编辑”链接。但是在这里的stackoverflow上,答案应该只是答案。据我所知,您不能在 node.js 中使用相对或部分 URL,因为没有“默认”上下文可以告诉 node.js 在未提供默认域时是什么。
    • 谢谢!我已经发现了错误,这让我大吃一惊:) 也感谢您对 stackoverflow 答案 /cmets 用法的解释,这对下次很有用。对于 URLS,/myapi 托管在同一个快速服务器中,这就是为什么我认为我可以使用 /myapi 代替完整的 URL 路径。
    【解决方案2】:

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

    '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/* 这样的网址而只使用/myapi/*

    谢谢@jfriend00

    【讨论】:

      猜你喜欢
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多