当循环中调用了异步函数时,Node.JS 将如何处理循环控制?
Posted
技术标签:
【中文标题】当循环中调用了异步函数时,Node.JS 将如何处理循环控制?【英文标题】:How will Node.JS process loop control while there's async function called in the loop? 【发布时间】:2012-12-27 22:29:16 【问题描述】:我的情况如下:有一个IP地址数组。我将测试每个 IP 以连接到远程服务器。如果一个 IP 连接,其余 IP 将被忽略并且不会连接。
我使用以下 Node.JS 代码来完成这项工作,但它似乎不起作用。请给出一些提示。谢谢!
// serverip is a var of string splitted by ";", e.g. "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 count 来控制循环是不好的,但是我不知道如何控制 Node.JS 循环,当循环中调用了异步函数时......
【问题讨论】:
【参考方案1】:因为您的 connect
和 error
回调都是异步的,所以它们都会在 for 循环完全完成后运行。
您需要做的是设置一组回调。例如,不要使用for
循环,而是将整个循环体包装在一个函数中。如果连接成功,那么就照常做,如果调用了error
回调,则再次执行包装函数。像这样的:
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
);
另一种解决方案是使用Async 库。
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);
【讨论】:
谢谢!对于您的第一个解决方案,我认为有这样的模式: var some_array = [...]; repeater(i) if( i @McArthorLee 是的!我扩展了我的例子。以上是关于当循环中调用了异步函数时,Node.JS 将如何处理循环控制?的主要内容,如果未能解决你的问题,请参考以下文章
node.js:如何在 forEach 循环中使用异步调用实现路由方法?