Node.js 如何有条件地处理带有承诺的for循环
我仍在试图找到一种方法,有条件地处理循环中的承诺,并能够打破循环 下面是一个简短的例子Node.js 如何有条件地处理带有承诺的for循环,node.js,asynchronous,ecmascript-6,promise,async-await,Node.js,Asynchronous,Ecmascript 6,Promise,Async Await,我仍在试图找到一种方法,有条件地处理循环中的承诺,并能够打破循环 下面是一个简短的例子 return new Promise(function (resolve, reject) { if (ipAddresses.length > 0) { let currentServer, agentOptions; for (let i = 0; i < i
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"));
}
})
返回新承诺(函数(解析、拒绝){
如果(ipAddresses.length>0){
让currentServer、agentOptions;
for(设i=0;i
问题是,我不需要并行运行所有请求,即Promise.all
或async.foreach
,但我需要依次调用每个Promise,如果条件为真,我需要打破循环,只要找到了可访问的服务器,就不要再发出任何请求
请建议处理此用例的正确方法。我已经寻找了很长时间,但仍然没有找到任何好的解决方案
谢谢
编辑
抱歉,是的
NetworkUntils.checkIfReachable()
返回promise假设NetworkUntils.checkIfReachable()
实际上是异步的(这是这个问题在nodejs中有意义的唯一上下文),并假设NetworkUntils.checkIfReachable()
返回承诺或可以轻松更改以返回承诺,然后您可以执行以下操作:
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);
}
findFirstReachableServer(IP地址){
如果(!IPAddresss | |!IPAddresss.length){
返回承诺。拒绝(新错误(“未提供服务器IP”);
}
让agentOptions={…};
设指数=0;
函数next(){
if(索引
此函数返回一个承诺,如果找到可访问的承诺,则该承诺将与ipAddress解析。如果未传入地址,未找到可访问地址,或者NetworkUtils.checkIfReachable()
因任何内部原因拒绝,则会拒绝
注意,要按顺序运行非阻塞异步操作,不能使用正常的
for
循环,因为每个操作都不会阻塞,因此for
循环不会等待它们(它只会在任何操作完成之前运行到完成)。因此,您必须使用不同的排序方法。有很多不同的方法可以做到这一点。由于您不一定要运行整个序列,因此我选择了手动排序,您可以在其中控制是否调用下一个迭代。假设NetworkUntils.checkIfReachable()
实际上是异步的(这是这个问题唯一有意义的上下文,并且在nodejs中似乎很可能)假设NetworkUntils.checkIfReachable()
返回一个承诺,或者可以很容易地更改为返回一个承诺,那么您可以执行以下操作:
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);
}
findFirstReachableServer(IP地址){
如果(!IPAddresss | |!IPAddresss.length){
返回承诺。拒绝(新错误(“未提供服务器IP”);
}
让agentOptions={…};
设指数=0;
函数next(){
if(索引
此函数返回一个承诺,如果找到可访问的承诺,则该承诺将与ipAddress解析。如果未传入地址,未找到可访问地址,或者NetworkUtils.checkIfReachable()
因任何内部原因拒绝,则会拒绝
注意,要按顺序运行非阻塞异步操作,不能使用正常的
for
循环,因为每个操作都不会阻塞,因此for
循环不会等待它们(它只会在任何操作完成之前运行到完成)。因此,您必须使用不同的排序方法。有很多不同的方法可以做到这一点。由于您不一定要运行整个序列,因此我选择了一个手动序列,您可以在其中控制是否调用下一个迭代。如果您标记了问题,那么使用它确实是一个不错的主意:
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
}
}
鉴于您对问题进行了标记,使用该选项确实不是一个坏主意:
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
}
}
NetworkUtils.checkIfReachable(agentOptions,ip)
是同步请求吗?我想是什么