Javascript 如何确保该循环在node.js中按预期运行
以下代码输出端口号40001两次,然后返回错误:Javascript 如何确保该循环在node.js中按预期运行,javascript,node.js,Javascript,Node.js,以下代码输出端口号40001两次,然后返回错误: Error: listen EADDRINUSE 我相信这是因为代码是异步的,在分配另一个端口之前,不会等待foreach循环的整个迭代 我应该使用哪个节点习惯用法来解决这个问题?我想在一个数组上循环,并在每次迭代中在不同的端口上建立phantomJS连接 posts.forEach(function(element, index, posts){ portscanner.findAPortNotInUse(40000, 60
Error: listen EADDRINUSE
我相信这是因为代码是异步的,在分配另一个端口之前,不会等待foreach循环的整个迭代
我应该使用哪个节点习惯用法来解决这个问题?我想在一个数组上循环,并在每次迭代中在不同的端口上建立phantomJS连接
posts.forEach(function(element, index, posts){
portscanner.findAPortNotInUse(40000, 60000, 'localhost', function(err, freeport) {
if(err) {
console.log(err);
}
console.log(freeport); //outputs 40001 twice then exits
phantom.create({'port': freeport}, function(ph){
return ph.createPage(function(page) {
return page.open("http://www.target.com/showthread.php?t="+posts[index].post_id, function(status) {
console.log("opened post? ", status);
return page.get('plainText', function(content){
console.log(content);
return ph.exit();
});
});
});
});
});
});
所以你是对的。这里的问题是,当您在第一次迭代(40001)中找到端口时,您不会在下一次迭代之前使用它,因此40001会被找到两次 这里有两种方法。要么使用延续,即创建下一步作为函数执行,然后在使用端口后调用延续 在这种情况下,只跟踪端口可能更容易。首先将基本端口定义为40000,当您找到一个端口时,将基本端口设置为
freeport+1
,并在该范围内搜索
var startPort = 40000
var endPort = 60000
posts.forEach(function(element, index, posts){
portscanner.findAPortNotInUse(startPort, endPort, 'localhost', function(err, freeport) {
if(err) {
return console.log(err);
}
console.log(freeport);
startPort = freeport + 1 // correct the start port to search from
phantom.create({'port': freeport}, function(ph){
return ph.createPage(function(page) {
return page.open("http://www.target.com/showthread.php?t="+posts[index].post_id, function(status) {
console.log("opened post? ", status);
return page.get('plainText', function(content){
console.log(content);
return ph.exit();
});
});
});
});
});
});
使用可连续系列继续(未经测试,但会给您一个想法)
所以你是对的。这里的问题是,当您在第一次迭代(40001)中找到端口时,您不会在下一次迭代之前使用它,因此40001会被找到两次 这里有两种方法。要么使用延续,即创建下一步作为函数执行,然后在使用端口后调用延续 在这种情况下,只跟踪端口可能更容易。首先将基本端口定义为40000,当您找到一个端口时,将基本端口设置为
freeport+1
,并在该范围内搜索
var startPort = 40000
var endPort = 60000
posts.forEach(function(element, index, posts){
portscanner.findAPortNotInUse(startPort, endPort, 'localhost', function(err, freeport) {
if(err) {
return console.log(err);
}
console.log(freeport);
startPort = freeport + 1 // correct the start port to search from
phantom.create({'port': freeport}, function(ph){
return ph.createPage(function(page) {
return page.open("http://www.target.com/showthread.php?t="+posts[index].post_id, function(status) {
console.log("opened post? ", status);
return page.get('plainText', function(content){
console.log(content);
return ph.exit();
});
});
});
});
});
});
使用可连续系列继续(未经测试,但会给您一个想法)
我最近遇到了同样的问题,并通过使用Math.Random生成一个开始端口值来修复它,然后添加500来获得结束端口值
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var startPort = getRandomInt(3000, 8000);
var endPort = startPort + 500;
portscan.findAPortNotInUse(startPort, endPort, '127.0.0.1', function (err, ports) {
.....
}
我最近遇到了同样的问题,并通过使用Math.Random生成一个开始端口值来修复它,然后添加500来获得结束端口值
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var startPort = getRandomInt(3000, 8000);
var endPort = startPort + 500;
portscan.findAPortNotInUse(startPort, endPort, '127.0.0.1', function (err, ports) {
.....
}
谢谢其他人也建议使用“异步串行”或process.nextTick()。对此有什么想法吗?这种方法有一些警告。延续会随着时间的推移表现得更好,但这会对搜索0个端口的范围造成影响。process.nextTick无法解决问题,因为phantom到startAsync serial可能需要任意数量的时间才能解决问题。手动延续与异步串行方法相同。我可以添加它作为一个例子。我添加了一个基于“连续系列”模块的例子。这只是一种风格/复杂性偏好。谢谢!其他人也建议使用“异步串行”或process.nextTick()。对此有什么想法吗?这种方法有一些警告。延续会随着时间的推移表现得更好,但这会对搜索0个端口的范围造成影响。process.nextTick无法解决问题,因为phantom到startAsync serial可能需要任意数量的时间才能解决问题。手动延续与异步串行方法相同。我可以添加它作为一个例子。我添加了一个基于“连续系列”模块的例子。这只是一种风格/复杂性偏好。