Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 用于循环和数组推送的节点JS_Javascript_Node.js_Asynchronous_Callback_Async.js - Fatal编程技术网

Javascript 用于循环和数组推送的节点JS

Javascript 用于循环和数组推送的节点JS,javascript,node.js,asynchronous,callback,async.js,Javascript,Node.js,Asynchronous,Callback,Async.js,我有1211434个IP地址需要转换成地理位置。我发现了一个api,它通过使用GET请求来回答这个问题。但问题是,当使用for循环时,我无法正确发送ip地址和接收描述 主要是我有两个问题: 我就是不能输出ip\u和\u info数组,也找不到原因。谁能告诉我出了什么问题吗 现在,我编写的代码可以检索我需要的所有信息,test_ip.txt中大约有200个ip地址。如果我尝试发送所有这些1M IP地址,是否会有潜在问题 有人能给我一些建议吗 非常感谢 我的代码如下: fs = require('f

我有1211434个IP地址需要转换成地理位置。我发现了一个api,它通过使用GET请求来回答这个问题。但问题是,当使用for循环时,我无法正确发送ip地址和接收描述

主要是我有两个问题:

  • 我就是不能输出
    ip\u和\u info
    数组,也找不到原因。谁能告诉我出了什么问题吗

  • 现在,我编写的代码可以检索我需要的所有信息,test_ip.txt中大约有200个ip地址。如果我尝试发送所有这些1M IP地址,是否会有潜在问题

  • 有人能给我一些建议吗

    非常感谢

    我的代码如下:

    fs = require('fs')
    async = require("async")
    http = require('http')
    
    ip_and_info = []
    // getIPInfo("1.171.58.24")
    
    
    fs.readFile("../test_ips.txt", "utf-8", (err, content, printArr) => {
    
        content = content.split("\n")
    
        async.each(content, (ip) => {
            content = getIPInfo(ip)
            // console.log(ip)
        }, (err) => {
            if (err) {
                console.log(err)
            } else {
                console.log(ip_and_info)
            }
        })
    
        // for (i in content) {
        //     ((ip) => {
        //         getIPInfo(ip)
        //     })(content[i])
        // }
    
    
    });
    
    
    
    function getIPInfo(ipAddress) {
    
        options = {
            host: 'freegeoip.net',
            path: '/csv/' + ipAddress
        }
    
        request = http.get(options, function(response) {
            // console.log('STATUS: ' + response.statusCode)
            // console.log('HEADERS: ' + JSON.stringify(response.headers))
    
            // Buffer the body entirely for processing as a whole.
            bodyChunks = []
            response.on('data', function(chunk) {
    
                bodyChunks.push(chunk)
    
            }).on('end', function() {
    
                body = Buffer.concat(bodyChunks)
                content = body.toString('ascii')
                ip_and_info.push(content)
                console.log(content)
                return content
    
            })
        })
    
        request.on('error', function(e) {
            console.log('ERROR: ' + e.message)
        })
    }
    

    非常感谢

    我认为您的问题可能是您在每个循环中都声明了'content'变量

    因此,也许可以将循环更改为此,这样就不会在每次循环执行时重置变量。我希望这能解决您的问题:

      IPList = content.split("\n")
    
        async.each(IPList, (ip) => {
            IPGeoLocation = getIPInfo(ip)
            console.log(IPGeoLocation)
        }, (err) => {
    
    至于用一百万个IP来做这件事,我看不出有什么大问题,只要你的电脑上有足够的内存。您可能希望添加一个“等待”呼叫,这样就不会对服务器进行如此一致的重击。他们可能会阻止你! 我会在每次通话之间加上

    sleep(1000);
    

    在获得IP之后。

    我认为您的问题可能是您在每个循环中都声明了'content'变量

    因此,也许可以将循环更改为此,这样就不会在每次循环执行时重置变量。我希望这能解决您的问题:

      IPList = content.split("\n")
    
        async.each(IPList, (ip) => {
            IPGeoLocation = getIPInfo(ip)
            console.log(IPGeoLocation)
        }, (err) => {
    
    至于用一百万个IP来做这件事,我看不出有什么大问题,只要你的电脑上有足够的内存。您可能希望添加一个“等待”呼叫,这样就不会对服务器进行如此一致的重击。他们可能会阻止你! 我会在每次通话之间加上

    sleep(1000);
    

    获得IP后。

    问题在于这一行

    content=getIPInfo(ip)

    getIPInfo应该是一个异步函数。一种方法是向函数发送回调,并在函数中返回回调中的输出

    async.each(content, getIPInfo, (err) => {
        if (err) {
            console.log(err)
        } else {
            console.log(ip_and_info)
        }
    })
    
    在getIPInfo函数中

    function getIPInfo(ipAddress, callback) {
      .....
      .....
      ip_and_info.push(content)
      callback();
    }
    

    此外,它将尝试发送所有1211434 IP的请求,而不是使用async.each使用async.eachSeries或async.eachLimit。

    问题在于这一行

    content=getIPInfo(ip)

    getIPInfo应该是一个异步函数。一种方法是向函数发送回调,并在函数中返回回调中的输出

    async.each(content, getIPInfo, (err) => {
        if (err) {
            console.log(err)
        } else {
            console.log(ip_and_info)
        }
    })
    
    在getIPInfo函数中

    function getIPInfo(ipAddress, callback) {
      .....
      .....
      ip_and_info.push(content)
      callback();
    }
    
    此外,它将尝试发送对所有1211434 IP的请求,而不是使用async.each使用async.eachSeries或async.eachLimit。

    使用承诺。
    使用
    let
    const
    关键字。说真的,我们不好玩。
    决定是使用
    还是使用
    ,并坚持使用它,它更具可读性

    有了Promise,就不需要异步或
    ip\u和\u info
    变量

    'use strict';
    
    const fs = require('fs'),
        http = require('http');
    
    fs.readFile('../test_ips.txt', 'utf-8', (err, content) => {
        content = content.split('\n');
    
        Promise.resolve().then(() => {
            return getAllIPInfo(content);
        }).then((ipsInfos) => {
            console.log('Info:' + ipsInfos);
        }).catch((error) => {
            console.error('Error: ' + error);
        });
    });
    
    function getAllIPInfo(ipsAddress) {
        return new Promise((resolve, reject) => {
            let ipsInfo = [];
            ipsAddress.reduce((previous, current, index, ips) => {
                return previous.then(() => {
                    return getIPInfo(ips[index]).then((content) => {
                        ipsInfo.push(content);
                        return Promise.resolve();
                    });
                });
            }, Promise.resolve()).then(() => {
                resolve(ipsInfo);
            }).catch((error) => {
                reject(error);
            });
        });
    }
    
    function getIPInfo(ipAddress) {
        return new Promise((resolve, reject) => {
            let options = {
                host: 'freegeoip.net',
                path: '/csv/' + ipAddress
            };
    
            http.get(options, function(response) {
                // console.log('STATUS: ' + response.statusCode)
                // console.log('HEADERS: ' + JSON.stringify(response.headers))
    
                // Buffer the body entirely for processing as a whole.
                let bodyChunks = [];
    
                response.on('data', function(chunk) {
                    bodyChunks.push(chunk);
                }).on('end', function() {
                    let body = Buffer.concat(bodyChunks),
                        content = body.toString('ascii');
    
                    resolve(content);
                });
            }).on('error', function(e) {
                console.log('ERROR: ' + e.message);
                reject(e);
            });
        });
    }
    
    使用承诺。
    使用
    let
    const
    关键字。说真的,隐式全局搜索并不有趣。
    决定是使用
    还是使用
    ,并坚持使用它,它更具可读性

    有了Promise,就不需要异步或
    ip\u和\u info
    变量

    'use strict';
    
    const fs = require('fs'),
        http = require('http');
    
    fs.readFile('../test_ips.txt', 'utf-8', (err, content) => {
        content = content.split('\n');
    
        Promise.resolve().then(() => {
            return getAllIPInfo(content);
        }).then((ipsInfos) => {
            console.log('Info:' + ipsInfos);
        }).catch((error) => {
            console.error('Error: ' + error);
        });
    });
    
    function getAllIPInfo(ipsAddress) {
        return new Promise((resolve, reject) => {
            let ipsInfo = [];
            ipsAddress.reduce((previous, current, index, ips) => {
                return previous.then(() => {
                    return getIPInfo(ips[index]).then((content) => {
                        ipsInfo.push(content);
                        return Promise.resolve();
                    });
                });
            }, Promise.resolve()).then(() => {
                resolve(ipsInfo);
            }).catch((error) => {
                reject(error);
            });
        });
    }
    
    function getIPInfo(ipAddress) {
        return new Promise((resolve, reject) => {
            let options = {
                host: 'freegeoip.net',
                path: '/csv/' + ipAddress
            };
    
            http.get(options, function(response) {
                // console.log('STATUS: ' + response.statusCode)
                // console.log('HEADERS: ' + JSON.stringify(response.headers))
    
                // Buffer the body entirely for processing as a whole.
                let bodyChunks = [];
    
                response.on('data', function(chunk) {
                    bodyChunks.push(chunk);
                }).on('end', function() {
                    let body = Buffer.concat(bodyChunks),
                        content = body.toString('ascii');
    
                    resolve(content);
                });
            }).on('error', function(e) {
                console.log('ERROR: ' + e.message);
                reject(e);
            });
        });
    }
    

    这不是问题所在,但你的代码正在沦为牺牲品(这是我贫血的小博客上的一篇文章)——声明你的变量。你需要承诺将所有异步进程推进数组并一起解决它。你的代码应该只打印空数组。这是因为循环将在getIPInfo()解析之前完成执行。正如@VinodLouis所说的,你可以通过承诺来解决这个问题。如果你对承诺不满意,请告诉我。我将尝试提出一个解决方案。可能的重复并不是问题所在,但您的代码正在沦为牺牲品(这是我贫乏的小博客上的一篇文章)——声明您的变量。您需要承诺将所有异步进程推送到数组中并一起解决。您的代码应该只打印空数组。这是因为循环将在getIPInfo()解析之前完成执行。正如@VinodLouis所说的,你可以通过承诺来解决这个问题。如果你对承诺不满意,请告诉我。我将尝试提出解决方案。此解决方案的可能副本将发送所有1211434 IP的请求。最好是创建IP块的promise对象,并在完成时移动到下一个IP块。@Golaksrangi:更新为按顺序调用ips。此解决方案将一起发送所有1211434 IP的请求。最好是创建IP块的promise对象,并在完成后移动到下一个IP块。@Golaksrangi:更新为按顺序调用IP