我遇到了以下示例(下面的示例1),这让我想知道我是否可以改变我处理Futures的方式并删除所有保留处理顺序的嵌套函数调用,但这会导致缩进我觉得有点乱。
但我的程序的更改版本无效。它没有保留处理顺序,也没有“等待”功能完成。例如,在从第一次调用(fGetUserInput)返回之前,调用了另一个后续函数。
为什么在例1中,顺序处理所有“第一级”“新未来”,但是在例2中,我改变了代码,不保留处理顺序。正在处理对fGetUserInput的调用时,处理其后的一个Futures?
是否“示例1”仅“有效”,因为所有语句都是同步的?
我遇到了对“runAsync”的引用。可以用来实现我想要的吗? (按顺序处理,没有任何缩进)。
// Example 1. Code that I encountered for Futures //
import 'dart:async';
main() {
new Future(() => print('1'))
.then((_) => print('a'))
.then((_) => print('b'));
new Future(() => print('2'))
.then((_) => print('c'))
.then((_) => print('d'));
new Future(() => print('3'))
.then((_) =>
new Future(() => print('e'))
.then((_) => print('f'))
);
new Future(() => print('4'))
.then((_) =>
new Future(() => print('g'))
.then((_) => print('d'))
);
}
以上导致以下控制台输出顺序: -
1 a b 2 c d 3 4 e f g d
我认为这是有道理的。
因此,我修改了我的代码以测试它如下: -
// Example 2. Altered version of my code which //
// does not preserve the order of processing, //
// which is necessary for program to function. //
new async.Future(() => fGetUserInput())
.then((lInput) {
iMaxIters = int.parse(lInput[4]);
tClearTable = (lInput[5] == "y");
iDivisor = fInitialize(iMaxIters);
tgPrint = false; // printing off
sUri =
"postgres://${lInput[1]}:${lInput[2]}@localhost:5432/${lInput[3]}";
sStartTime = lInput[7];
})
.catchError((oError) => fFatal("Get User Input", oError));
new async.Future(() => fConnectToDb(sUri, sStartTime))
.then((bool tConnected) {
if (ogDb == null)
fFatal("Unable to connect to database", "");
print ("Processing database ......");
})
.catchError((oError) => fFatal("Connect to Db", oError));
new async.Future(() => fClearTable(tClearTable))
.then((sResult) => print (sResult+"\n"))
.catchError((oError) => fFatal("Clear Table", oError));
new async.Future(() => fProcessInserts(iMaxIters, iDivisor))
.then((sResult) => print (""))
.catchError((oError) => fFatal("Process Inserts", oError));
new async.Future(() => fSetupRandKeys())
.then((sResult) => print (""))
.catchError((oError) => fFatal("Setup Random Keys", oError));
new async.Future(() => fProcessUpdates(iMaxIters, iDivisor))
.then((sResult) {
String sTotValue = fFormatAmount(igGrandTotAmt, true, 2);
fPrint ("Grand Total added to database = \$${sTotValue}");
ogDb.close();
exit(0);
})
.catchError((oError) => fFatal("Process Updates", oError));
}
void fFatal (String sMessage, Error oError) {
print("\n\nFatal Error. $sMessage\n${oError}");
exit(1);
}
async.Future<String> fProcessInserts(int iMaxIters, int iDiv) {
async.Completer oCompleter = new async.Completer<String>();
int iTot = 0;
Function fLoop;
print ("\nProcessing Inserts ......");
fResetAndStartWatch();
以下是我在上述更改之前的代码,以下示例3似乎正常工作。我不喜欢缩进的程度,并且在更多函数调用的情况下,这会增加缩进的程度。我希望有一种更优雅的方式去做。
// Example 3: The original version of my code //
// which does preserve the order of processing //
void main() {
print("");
String sCheckPoint = "Get User Input";
fGetUserInput()
.then((lInput) {
int iMaxIters = int.parse(lInput[4]);
bool tClearTable = (lInput[5] == "y");
int iDiv = fInitialize(iMaxIters);
tgPrint = false; // printing off
String sUri =
"postgres://${lInput[1]}:${lInput[2]}@localhost:5432/${lInput[3]}";
sCheckPoint = "Connect to Database";
fConnectToDb(sUri, lInput[7]).then((bool tConnected) {
if (ogDb == null)
fFatal(sCheckPoint, "Unable to conenct to Db");
print ("Processing database ......");
sCheckPoint = "Clear Table";
fClearTable(tClearTable).then((sResult) {
print (sResult+"\n");
sCheckPoint = "Process Inserts";
fProcessInserts(iMaxIters, iDiv).then((sResult) {
print;
sCheckPoint = "Set-up Random Keys";
fSetupRandKeys().then((sResult) {
print;
sCheckPoint = "Process Updates";
fProcessUpdates(iMaxIters, iDiv).then((sResult) {
String sTotValue = fFormatAmount(igGrandTotAmt, true, 2);
fPrint ("Grand Total added to database = \$${sTotValue}");
ogDb.close();
exit(0);
});
});
});
});
});
})
.catchError((oError) => fFatal(sCheckPoint, oError));
}
void fFatal (String sMessage, Error oError) {
print("\n\nFatal Error. $sMessage\n${oError}");
exit(1);
}
async.Future<String> fProcessInserts(int iMaxIters, int iDiv) {
async.Completer oCompleter = new async.Completer<String>();
int iTot = 0;
Function fLoop;
print ("Processing Inserts ......");
fResetAndStartWatch();
答案 0 :(得分:1)
请记住,你可以连接期货,这会减少你的缩进量。
缺点是您没有获得嵌套作用域,如果您有多个值在异步块之间传播,这可能很有用,但这可以通过几种方式解决。
以下是带链接的示例3:
// Example 3 with chaining
void main() {
String checkPoint = "Get User Input";
getUserInput().then((input) {
int maxIters = int.parse(input[4]);
bool clearTable = (input[5] == "y");
int div = initialize(maxIters);
shouldPrint = false; // printing off
String uri =
"postgres://${input[1]}:${input[2]}@localhost:5432/${input[3]}";
checkPoint = "Connect to Database";
return connectToDb(uri, input[7]).then((bool connected) {
if (db == null)
fatal(checkPoint, "Unable to conenct to Db");
print ("Processing database ......");
checkPoint = "Clear Table";
return clearTable(shouldClearTable);
}).then((result) {
print (result+"\n");
checkPoint = "Process Inserts";
return processInserts(maxIters, div);
}).then((result) {
print('');
checkPoint = "Set-up Random Keys";
return setupRandKeys();
}).then((result) {
print('');
checkPoint = "Process Updates";
return processUpdates(maxIters, div);
}).then((result) {
String totValue = formatAmount(grandTotAmt, true, 2);
print("Grand Total added to database = \$${totValue}");
return db.close();
// exit(0); pretty much never call exit()
});
}).catchError((error) => fatal(checkPoint, error));
}
编辑:哎呀,仔细观察我对范围问题有所了解......我添加了一个嵌套级别,只是为了捕获以下块可访问的范围内所需的变量。我也删除了匈牙利语符号,因为......不要在Dart中这样做:)