javascript - 我怎样才能确保这个循环在node.js中按预期运行

标签 javascript node.js

以下代码输出端口号 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/

相关文章:

javascript - jQuery - 选择 <tr> 的第一个 <td> 中的第一个 <a>

javascript - 使用 jQuery.getScript() 赋值后全局变量未定义

javascript - 无法修复 Mongoose 覆盖模型错误

javascript - Chart.js "display:none"问题

javascript - 如何根据 JavaScript 中哪个 nodeList 不为空来设置变量?

javascript - 使用 jQuery 查找链接时 document.links 是否更快?

node.js - "image-min"在 Node js 中的 "multer"内不起作用

node.js - 如何在nodejs v6.11.3中使用 "import"

javascript - 在 Node.js 集群中提供静态文件?

node.js - socketIO客户端默认监听什么端口?