Comment puis-je m’assurer que cette boucle fonctionne comme prévu dans le fichier node.js

Le code suivant renvoie le numéro de port 40001 deux fois, puis se ferme avec une erreur:

Error: listen EADDRINUSE 

Je pense que c’est parce que le code est asynchrone et n’attend pas une itération complète de la boucle foreach avant d’affecter un autre port.

Quel langage de nœud dois-je utiliser pour résoudre ce problème? Je souhaite effectuer une boucle sur un tableau et établir une connexion fantôme sur un port différent à chaque itération.

 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(); }); }); }); }); }); }); 

Alors tu as raison. Le problème ici est que lorsque vous trouvez le port lors de la première itération (40001), vous ne le consumz pas avant la prochaine itération. 40001 est donc trouvé deux fois.

Donc, il y a 2 approches ici. Soit vous utilisez une continuation, c’est-à-dire que vous créez une étape suivante à exécuter en tant que fonction, puis appelez la continuation après avoir utilisé le port.

Dans ce cas, il est probablement plus facile de garder une trace du port. Commencez par définir un port de base à 40000, lorsque vous trouvez un port, définissez le port de base sur freeport + 1 et effectuez une recherche sur cette plage.

 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(); }); }); }); }); }); }); 

Continuation en continu-series (non testé mais devrait vous donner une idée)

 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(); }); }); }); }); }); } 

J’ai récemment rencontré le même problème et je l’ai corrigé en utilisant Math.Random pour générer une valeur de port de début et je viens d’append 500 pour obtenir la valeur du port de fin.

 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) { ..... }