Dart async.Future async.Completer-如何;“继续”;如果有错误

Dart async.Future async.Completer-如何;“继续”;如果有错误,dart,Dart,如能在以下方面提供帮助,将不胜感激。我正在编写一些控制台测试程序,我希望能够从终端输入一些参数(我不想使用命令行参数-参数太多)。我尝试过一些变化,但我找不到如何实现这一点。以下是终端输入测试的最新版本。这个程序的问题是,如果遇到错误,完成程序会自动关闭,我想从Main()或fGetNumber()函数继续。虽然我能理解为什么这个程序不起作用,但它说明了我需要实现什么——重新输入数字,但我找不到如何实现。如果输入了有效的数字,则没有问题。如果输入了无效的号码,我无法找到如何重新输入该号码 代码如

如能在以下方面提供帮助,将不胜感激。我正在编写一些控制台测试程序,我希望能够从终端输入一些参数(我不想使用命令行参数-参数太多)。我尝试过一些变化,但我找不到如何实现这一点。以下是终端输入测试的最新版本。这个程序的问题是,如果遇到错误,完成程序会自动关闭,我想从Main()或fGetNumber()函数继续。虽然我能理解为什么这个程序不起作用,但它说明了我需要实现什么——重新输入数字,但我找不到如何实现。如果输入了有效的数字,则没有问题。如果输入了无效的号码,我无法找到如何重新输入该号码

代码如下,我遇到的问题突出显示为“//”:

将“dart:async”导入为异步;
导入“dart:io”;
void main(){
fGetNumber(“输入迭代次数:”,0,999999)
.然后((整数){
打印(“主:所选迭代=${iIters}”);
如果(iIters==null){
打印(“主要:无效的迭代次数:${iIters}”);
}否则{
FpProcessData(iIters);
}
打印(“主完成”);
});
}
async.Future fGetNumber(字符串sPrompt、int-iMin、int-iMax){
打印(“在fGetNumber中”);
整数=0;
async.Completer-oCompleter=new async.Completer();
而(!oCompleter.isCompleted){///此循环不起作用
返回fGetUserInput(sPrompt)。然后((字符串站点){
iIters=int.parse(站点);
如果(iItersiMax)抛出新异常(“无效”);
o完成者。完成者(iIters);
返回oCompleter.future;
}).catchError(()=>print(“无效-数字必须从${iMin}到${iMax}”)
).whenComplete(()=>print(“fGetNumber-whenComplete”);//总是在这里
}
print(“在fGetNumber中(在函数末尾)”;///它永远不会出现在这里
}
async.Future fGetUserInput(字符串sPrompt){
打印(“在fGetUserInput中”);
async.Completer-oCompleter=new async.Completer();
stdout.write(sPrompt);
async.Stream-oStream=stdin.transform(新的StringDecoder());
async.streamb;
oSub=oStream.listen((字符串sData){
完成($sData);
oSub.cancel();
});
返回oCompleter.future;
}
无效fProcessData(整数){
打印(“在fProcessData中”);
对于(int IPO=1;IPO
//这个循环不起作用

当然是这样的——您只需输入一次,然后立即返回,从而离开循环和方法

//总是来这里

这是因为无论成功还是出错,whenComplete()
总是被调用

//它永远不会到达这里

因为您已经从方法中返回

那么可以做什么呢?

最简单的方法是不要依赖
fGetUserInput()
。在
fGetNumber
中收听
stdin
,只有在输入有效的情况下才能完成完成/取消订阅:

async.Future fGetNumber(字符串sPrompt、int-iMin、int-iMax){
打印(“在fGetNumber中”);
async.Completer-oCompleter=new async.Completer();
stdout.write(sPrompt);
async.Stream-oStream=stdin.transform(新的StringDecoder());
async.streamb;
oSub=oStream.listen((字符串sData){
试一试{
int iIters=int.parse(sData);
如果(iItersiMax)抛出新异常(“无效”);
o完成者。完成者(iIters);
oSub.cancel();
}捕获(e){
打印(“无效-数字必须从${iMin}到${iMax}”);
stdout.write(sPrompt);
}
});
返回oCompleter.future;
}
有其他选择吗?

当然。可能有很多很多方法可以做到这一点。例如:

async.Future fGetNumber(字符串sPrompt、int-iMin、int-iMax){
打印(“在fGetNumber中”);
async.Completer-oCompleter=new async.Completer();
fGetUserInput(sPrompt,oCompleter,(字符串站点){
试一试{
int iIters=int.parse(站点);
如果(iItersiMax)抛出新异常(“无效”);
归还者;
}捕获(e){
打印(“无效-数字必须从${iMin}到${iMax}”);
stdout.write(sPrompt);
}
返回null;
});
返回oCompleter.future;
}
void fGetUserInput(字符串sPrompt、异步.Completer-oCompleter、动态inputValidator(字符串sData)){
打印(“在fGetUserInput中”);
stdout.write(sPrompt);
async.Stream-oStream=stdin.transform(新的StringDecoder());
async.streamb;
oSub=oStream.listen((字符串sData){
var d=输入验证程序(sData);
如果(d!=null){
完成(d);
oSub.cancel();
}
});
}
如果你真的觉得Dart团队应该解决一些问题,你可以编写一个。但是
完成器
设计为只完成一次。无论你写什么代码,你都不能一次又一次地循环完成

//这个循环不起作用

当然是这样的——您只需输入一次,然后立即返回,从而离开循环和方法

//总是来这里

这是因为无论成功还是出错,whenComplete()总是被调用

//它永远不会到达这里

因为您已经从方法中返回

那么可以做什么呢?

最简单的方法是不要依赖
fGetUserInput()
。在
fGetNumber
中收听
stdin
,只有在输入有效的情况下才能完成完成/取消订阅:

async.Future fGetNumber(字符串sPrompt、int-iMin、int-iMax){
打印(“在fGetNumber中”);
async.Completer-oCompleter=new async.Completer();
stdout.write(sPrompt);
异步流