在循环中调用asynchronous函数时,Node.JS如何处理循环控制?

我的情况如下:有一个IP地址的数组。 我将testing每个IP连接到远程服务器。 如果一个IP连接,其余的IP将被忽略,不会被连接。

我使用了下面的Node.JS代码来完成这项工作,但似乎无法正常工作。 请提供一些提示。 谢谢!

// serverip is a var of string splitted by ";", eg "ip1;ip2;ip3" var aryServerIP = serverip.split(";"); console.log(aryServerIP); var ipcnt = aryServerIP.length; // ipcnt = 3, for example for (ip in aryServerIP) { console.log("to process: " + ipcnt); // error here: always print 3 var net = require('net'); var client = new net.Socket(); var rdpport = 3389; client.connect(rdpport, aryServerIP[ip], function(){ console.log("socket connected to " + aryServerIP[ip] + ":" + rdpport); client.destroy(); if (0 != ipcnt) { // do some real connection work about aryServerIP[ip]. ipcnt--; } }); client.on('error', function(){ console.log("fail to connect to " + aryServerIP[ip] + ":" + rdpport); ipcnt--; }); } 

我知道使用ipcnt计数来控制循环是坏的,但我不知道如何控制Node.JS循环,当循环中调用asynchronous函数…

因为connecterrorcallback都是asynchronous的,所以它们都会在for循环完成之后运行。

你需要做的是设置一组callback。 例如,而不是使用for循环,将整个循环体包装在一个函数中。 如果连接成功,那么只要按照通常的方式进行操作即可,如果调用errorcallback函数,则再次执行包装函数。 像这样的东西:

 var async = require('async'); var net = require('net'); var rdpport = 3389; function tryConnections(aryServerIP, callback){ function connect(i){ if (i === aryServerIP.length) return callback(); var client = new net.Socket(); client.connect(rdpport, aryServerIP[i], function(){ callback(client); }); client.on('error', function(){ connect(i + 1) }); } connect(0) } tryConnections(serverip.split(";"), function(client){ if (client) // Successfully connected to something else // all ips failed }); 

另一个解决scheme是使用asynchronous库。

 function tryConnections(aryServerIP, callback){ async.detectSeries(aryServerIP, function(ip, cb){ var client = new net.Socket(); client.connect(rdpport, ip, function(){ cb(client); }); client.on('error', function(){ cb(); }); }, callback); }