Javascript 用于循环和数组推送的节点JS
我有1211434个IP地址需要转换成地理位置。我发现了一个api,它通过使用GET请求来回答这个问题。但问题是,当使用for循环时,我无法正确发送ip地址和接收描述 主要是我有两个问题: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
ip\u和\u info
数组,也找不到原因。谁能告诉我出了什么问题吗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