我仍在学习Dart和OOP,不能完全正确。问题是由于查询的延迟,_batch.addAll()
在从内部ForEach填充_invDetails
之前执行。我该如何正确组织?
Future<Response> exportAccpac() async {
final Map<String, dynamic> _inv = {'inv': []};
final Map<String, dynamic> _invDetails = {'invDet': []};
final Map<String, dynamic> _batch = {};
final _qExpenses = Query<UserCompany>(context);
_qExpenses.where((e) => e.company.id).equalTo(companyId);
_qExpenses
.join(object: (e) => e.user)
.join(set: (u) => u.expense)
.where((d) => d.date)
.lessThanEqualTo(date);
final _expenseList = await _qExpenses.fetch();
_expenseList.forEach((e) {
_inv['inv'].add(
{
// a bunch of stuff here using e
},
);
e.user.expense.forEach((userExpense) async {
final _qGlCode = Query<GlCode>(context)
..where((g) => g.user_type.id).equalTo(_userTypeId)
..where((g) => g.company.id).equalTo(companyId)
..where((g) => g.expense_type.id).equalTo(userExpense.expense_type.id);
final _glCodes = await _qGlCode.fetch();
_invDetails['invDet'].add({
// a bunch of stuff here using glCodes
});
});
});
_batch..addAll(_inv)..addAll(_invDetails);
}
答案 0 :(得分:1)
通常避免使用forEach
-尤其是async
。重新组织代码,如下所示:
for (var userExpense in e.user.expense) {
final _qGlCode = Query<GlCode>(context)
..where((g) => g.user_type.id).equalTo(_userTypeId)
..where((g) => g.company.id).equalTo(companyId)
..where((g) => g.expense_type.id).equalTo(userExpense.expense_type.id);
final _glCodes = await _qGlCode.fetch();
_invDetails['invDet'].add({
// a bunch of stuff here using glCodes
});
}
这具有按顺序执行GL代码查询的效果,而以前您是并行启动它们的,但是没有办法等待它们完成。 (为此,您应该使用Future.wait
,但这在这里不需要。)
您也可以将外部forEach
替换为for
。
答案 1 :(得分:0)
您可以将forEach置于异步函数下,并返回_inv最终变为:
final _expenseList = await _qExpenses.fetch();
final _inv = await _yourNewFunction();
_batch..addAll(_inv)..addAll(_invDetails);