Dart 异步期货按顺序运行到完成

Dart 异步期货按顺序运行到完成,dart,Dart,我遇到了下面的Futures示例(下面的示例1),这让我想知道是否可以改变处理Futures的方式,删除所有保留处理顺序的嵌套函数调用,但这会导致缩进,我发现缩进有点混乱 然而,我的程序的修改版本不起作用。它不保留处理顺序,也不“等待”函数完成。例如,在第一次调用(fGetUserInput)返回之前,调用了另一个后续函数 为什么在示例1中,所有“1级”“新未来”都是按顺序处理的,而在示例2中,我修改的代码中,处理顺序没有保留。在处理对fGetUserInput的调用时,会处理它后面的一个未来

我遇到了下面的Futures示例(下面的示例1),这让我想知道是否可以改变处理Futures的方式,删除所有保留处理顺序的嵌套函数调用,但这会导致缩进,我发现缩进有点混乱

然而,我的程序的修改版本不起作用。它不保留处理顺序,也不“等待”函数完成。例如,在第一次调用(fGetUserInput)返回之前,调用了另一个后续函数

为什么在示例1中,所有“1级”“新未来”都是按顺序处理的,而在示例2中,我修改的代码中,处理顺序没有保留。在处理对fGetUserInput的调用时,会处理它后面的一个未来

是否因为所有语句都是同步的,所以“示例1”只能“起作用”

我遇到了对“runAsync”的引用。这能用来实现我想要的吗?(按顺序加工,无需全部压痕)

//示例1。我在未来遇到的代码//
导入“dart:async”;
main(){
新未来(()=>打印('1'))
.然后(())=>打印('a'))
。然后()=>打印('b');
新未来(()=>打印('2'))
.然后(())=>打印('c'))
。然后()=>打印('d');
新未来(()=>打印('3'))
.然后(())=>
新未来(()=>print('e'))
.然后(()=>打印('f'))
);
新未来(()=>打印('4'))
.然后(())=>
新未来(()=>打印('g'))
.然后(()=>打印('d'))
);
}
上述结果产生以下控制台输出顺序:-

1 a b 2 c d 3 4 e f g d 1 a b 2 c d 3 4 e f g d 我认为这是有道理的

因此,我修改了我的代码来测试它,如下所示:-

//示例2。修改了我的代码版本//
//不保留处理顺序//
//这是程序运行所必需的//
新建async.Future(()=>fGetUserInput())
.然后((lInput){
iMaxIters=int.parse(lInput[4]);
tClearTable=(lInput[5]=“y”);
iDivisor=有限化(iMaxIters);
tgPrint=false;//打印关闭
苏里=
“postgres://${lInput[1]}:${lInput[2]}@localhost:5432/${lInput[3]}”;
sStartTime=lInput[7];
})
.catchError((oError)=>fFatal(“获取用户输入”,oError));
新的async.Future(()=>fConnectToDb(sUri,sStartTime))
.然后((布尔t连接){
if(ogDb==null)
fFatal(“无法连接到数据库”,”;
打印(“处理数据库……”);
})
.catchError((oError)=>fFatal(“连接到数据库”,oError));
新的async.Future(()=>fClearTable(tClearTable))
。然后((sResult)=>打印(sResult+“\n”))
.catchError((oError)=>fFatal(“清除表格”,oError));
新的async.Future(()=>fprocessinerts(iMaxIters,iDivisor))
.然后((sResult)=>打印(“”)
.catchError((oError)=>fFatal(“过程插入”,oError));
新的async.Future(()=>fSetupRandKeys())
.然后((sResult)=>打印(“”)
.catchError((oError)=>fFatal(“设置随机键”,oError));
新的async.Future(()=>fProcessUpdates(iMaxIters,iDivisor))
.然后((sResult){
字符串sTotValue=fFormatAmount(IGGrandToAmt,true,2);
fPrint(“添加到数据库的总计=\${sTotValue}”);
ogDb.close();
出口(0);
})
.catchError((oError)=>fFatal(“过程更新”,oError));
}  
void fFatal(字符串错误消息,错误){
打印(“\n\n致命错误。$sMessage\n${oError}”);
出口(1);
}
async.Future fProcessInserts(int-iMaxIters,int-iDiv){
async.Completer-oCompleter=new async.Completer();
int-iTot=0;
功能布局;
打印(“\n处理插入件…”);
fResetAndStartWatch();
下面是我在上述更改之前的代码,下面的示例3似乎可以正常工作。我不喜欢缩进的范围,在有更多函数调用的情况下,这会增加缩进的范围。我希望有一种更优雅的方法来实现

//示例3:我的代码的原始版本//
//这会保留处理的顺序//
void main(){
打印(“”);
字符串sCheckPoint=“获取用户输入”;
fGetUserInput()
.然后((lInput){
int iMaxIters=int.parse(lInput[4]);
bool tClearTable=(lInput[5]=“y”);
int iDiv=有限化(iMaxIters);
tgPrint=false;//打印关闭
串苏里=
“postgres://${lInput[1]}:${lInput[2]}@localhost:5432/${lInput[3]}”;
sCheckPoint=“连接到数据库”;
fConnectToDb(sUri,lInput[7])。然后((bool t连接){
if(ogDb==null)
fFatal(sCheckPoint,“无法连接到Db”);
打印(“处理数据库……”);
sCheckPoint=“清除表格”;
fClearTable(tClearTable)。然后((sResult){
打印(sResult+“\n”);
sCheckPoint=“进程插入”;
fprocessinerts(iMaxIters,iDiv)。然后((sResult){
印刷品;
sCheckPoint=“设置随机键”;
fSetupRandKeys()。然后((sResult){
印刷品;
sCheckPoint=“流程更新”;
fProcessUpdates(iMaxIters,iDiv)。然后((sResult){
字符串sTotValue=fFormatAmount(IGGrandToAmt,true,2);
fPrint(“添加到数据库的总计=\${sTotValue}”);
ogDb.close();
出口(0);
});
});
});
});
});
})
.catchError((oError)=>fFatal(sCheckPoint,oError));
}
void fFatal(字符串错误消息,错误){
打印(“\n\n致命错误。$sMessage\n${oError}”);
出口(1);
}
async.Future fProcessInserts(int-iMaxIters,int-iDiv){
async.Completer-oCompleter=new async.Completer();
int-iTot=0;
功能布局;
打印(“处理插入物……”);
fResetAndStartWatch();

记住,你可以连锁期货,这将大大减少你的缩进

缺点是没有嵌套的作用域