dart - 如何正确构建此 Dart 异步代码?
问题描述
我还在学习 Dart 和 OOP 并且不能完全正确地做到这一点。问题是由于查询的延迟,_batch.addAll()
执行之前_invDetails
是从内部 ForEach 填充的。我该如何正确地构建它?
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);
}
解决方案
一般避免使用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
您也可以用 a替换外部for
。
推荐阅读
- python - 你如何在 Python 中使用 pdflatex?
- makefile - 当 -e 用作前缀时,MAKE 中的 addprefix 无法正常工作
- apache - Apache 2.4 白名单一个网址
- sql - 我如何表示一个由 3 个其他实体组成的实体?
- slack-api - 我怎样才能让它看起来像一个机器人正在输入松弛?
- blazor - Blazor、Debug.WriteLine 未输出到 Google Chrome 控制台
- c++ - Valgrind POSIX timer_create()“可能丢失”
- amazon-web-services - 有没有办法从当前资源生成 CloudFormation 模板?
- swift - 如何将数组作为表单数据传递给邮递员
- javascript - 无法使用 JavaScript 在 Appium 中使用 By.name 定位器单击元素