以下代码输出端口号 40001 两次,然后错误退出:
Error: listen EADDRINUSE
我相信这是因为代码是异步的,并且在分配另一个端口之前不会等待 foreach 循环的整个迭代。
我应该使用哪种 Node 惯用法来解决这个问题?我想循环一个数组并在每次迭代的不同端口上建立 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();
});
});
});
});
});
});
继续使用 continuable-series(未经测试,但应该给你一个想法)
var phantom = require("phantom")
var portscanner = require("portscanner")
var series = require("continuable-series");
module.exports = function processPosts(posts) {
var callInSeries = posts.map(function (post) {
return phantomPage.bind(null, post)
});
series(callInSeries, function (err) {
if (err) {
console.log(err)
}
}
}
function phantomPage(post, callback) {
portscanner.findAPortNotInUse(40000, 60000, 'localhost', function(err, freeport) {
if (err) {
return callback(err);
}
phantom.create({'port': freeport}, function(ph){
// Now that we have opened the port, we can callback immediately
// starting the next iteration
callback(null)
return ph.createPage(function(page) {
return page.open("http://www.target.com/showthread.php?t="+post.post_id, function(status) {
console.log("opened post? ", status);
return page.get('plainText', function(content){
console.log(content);
return ph.exit();
});
});
});
});
});
}
关于javascript - 我怎样才能确保这个循环在node.js中按预期运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20355956/