我仍然试图找到一种方法来有条件地处理循环中的promise,并且能够突破循环。
这是一个简短的例子
nodeToDelete
问题是我不需要并行运行所有请求rootNode
或return new Promise(function (resolve, reject) {
if (ipAddresses.length > 0) {
let currentServer, agentOptions;
for (let i = 0; i < ipAddresses.length; i++) {
currentServer = ipAddresses[i];
agentOptions = {
};
// We need to block here
let isReachable = NetworkUtils.checkIfReachable(agentOptions, ip);
if (isReachable) {
resolve(currentServer);
// Break out of the loop
return currentServer;
}
else {
// Continue looping and trying to find a working server
}
}
reject(new Error("No working servers found"));
}
else {
resolve(new Error("No servers ips provided"));
}
})
,但我宁愿需要连续调用每个promise,如果条件为true,我需要突破循环,并且在我找到可到达的服务器时不要再做任何进一步的请求。
请建议处理此用例的正确方法是什么。我一直在寻找很长一段时间,但仍然没有找到任何好的解决方案。
由于
编辑
抱歉,是的Promise.all
返回承诺
答案 0 :(得分:2)
假设NetworkUntils.checkIfReachable()
实际上是异步的(这是这个问题有意义的唯一上下文,似乎可能在nodejs中),并假设NetworkUntils.checkIfReachable()
返回一个promise或者可以很容易地更改为返回一个promise ,那么你可以做到以下几点:
findFirstReachableServer(ipAddresses) {
if (!ipAddresses || !ipAddresses.length) {
return Promise.reject(new Error("No servers ips provided"));
}
let agentOptions = {...};
let index = 0;
function next() {
if (index < ipAddresses.length) {
let ipAddress = ipAddresses[index++];
return NetworkUtils.checkIfReachable(agentOptions, ipAddress).then(function(isReachable) {
if (!isReachable) {
return next();
} else {
return ipAddress;
}
})
} else {
return new Error("No working servers found");
}
}
return Promise.resolve().then(next);
}
此函数返回一个使用ipAddress解析的promise,如果找到了可到达的promise。如果没有传入任何地址,找不到可到达的地址,或者NetworkUtils.checkIfReachable()
因任何内部原因拒绝,则拒绝。
注意,要按顺序运行非阻塞异步操作,您不能使用普通for
循环,因为每个单独的操作都不会阻止,因此for
循环赢了&# 39;等待它们(它将在任何操作完成之前运行完成)。因此,您必须使用不同的排序方法。有很多不同的方法可以做到这一点。由于您不一定要运行整个序列,因此我选择了手动排序,您可以控制是否调用下一次迭代。
答案 1 :(得分:0)
鉴于你标记了问题async-await,使用它确实不是一个坏主意:
async function findWorkingServer(ipAddresses) {
if (ipAddresses.length > 0) {
for (const currentServer of ipAddresses) {
const agentOptions = { … };
const isReachable = await NetworkUtils.checkIfReachable(agentOptions, ip);
// We do "block" here ^^^^^
if (isReachable) {
return currentServer;
}
}
throw new Error("No working servers found");
} else {
return new Error("No servers ips provided"); // I think you meant to `throw` here
}
}