我目前正在学习如何使用NodeJS并编写这个相对简单的函数以固定的间隔运行。此功能的目的是检索新创建的Droplet并更新其IP地址。
router.newDroplets = setInterval(function() {
Server.find().then(function(svrs) {
for (var i = 0; i < svrs.length; i++) {
if (svrs[i].status == "Creating") {
library.getDropletById(svrs[i].serverid).then(function(svr) {
if (svr.droplet) {
for (var j = 0; j < svr.droplet.networks.v4.length; j++) {
if(svr.droplet.networks.v4[j].type == 'public') {
var ip_address = svr.droplet.networks.v4[j].ip_address;
console.log(ip_address);
Server.update({serverid: svr.droplet.id}, {ipaddress: ip_address, status: "Online"}, function(error, n) {
if (error) console.log(error);
else console.log(n);
});
}
}
} else if (svr.id) {
// NOTE THIS LINE
console.log(svrs);
}
}, function() {
});
}
}
}, function() {
});
}, 2500);
奇特的行为是上面标出的行。
当我使用console.log(svrs)
时,我在MongoDB的Server集合中获得了一系列JSON文档。但是,当我使用console.log(svrs[i])
时,会在控制台中记录undefined
。即使我在for循环之外声明var i = 0;
,也会发生这种情况。为什么会发生这种情况?如何访问svrs[i]
?
答案 0 :(得分:2)
承诺的工作方式是承诺链以异步方式运行。到代码运行时,i
等于svrs.length
,因此svrs[i]
将为undefined
。这是因为for循环在调用任何then
回调之前完全执行。您可以将代码转换为使用Array.prototype.forEach
所以你可以试试像
这样的东西svrs.forEach(function(svrInstance, i) {
if (svrInstance.status == "Creating") {
library.getDropletById(svrInstance.serverid).then(function(svr) {
if (svr.droplet) {
...
} else if (svr.id) {
console.log(svrs[i]);
}
});
}
});