gpt4 book ai didi

flutter - Flutter 中的 await 关键字不等待

转载 作者:行者123 更新时间:2023-12-04 08:21:24 24 4
gpt4 key购买 nike

我正在通过一个小型移动应用程序学习 Dart 和 Flutter。我已经阅读了我发现的关于 await 关键字的所有内容,但仍然有我不明白的问题。下面是简化代码。我删除了所有我认为对理解我的问题没有必要的东西。如果缺少重要的东西,请告诉我。
我的问题是 TODO(第 7 行)下方的以下行: List Locations = await _useCaseManager.findLocations();在这种方法中,我查询数据库。我希望应用程序等到查询完成并返回数据。
我在 build() 方法中调用了 _findFirstLocation() 方法。但是 Flutter 不会等待数据。它继续执行其余代码,尤其是 createNextAppointmentsList() 方法。在这个方法中,我需要应用程序应该等待 future 的数据 - 属性 _selectedLocation。但是因为 Flutter 没有等待,_selectedLocation 为空。
这是类(class)的相关部分。

class _AppointmentsOverviewScreenState extends State<AppointsmentsOverviewScreen> {
UseCaseManager _useCaseManager;
Location _selectedLocation;

void _findFirstLocation() async {
// TODO Hier wartet er schon wieder nicht.
List<Location> locations = await _useCaseManager.findLocations();
_selectedLocation = locations.first;
print(_selectedLocation);
}

@override
Widget build(BuildContext context) {
_useCaseManager = UseCaseManager.getInstance();
_findFirstLocation();

return Scaffold(
appBar: AppBar(
title: Text(LabelConstants.TITLE_APPOINTMENT_OVERVIEW),
),
body: Column(
children: <Widget>[
Container(child: createNextAppointmentsList(),)
],
),
);
}

Widget createNextAppointmentsList() {
return FutureBuilder<List<Appointment>>(
future: _useCaseManager.findAppointmentsForActiveGarbageCans(_selectedLocation.locationId),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text(snapshot.data[index].garbageCanName),
subtitle: Text(snapshot.data[index].date),
);
},
);
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
return Center(child: CircularProgressIndicator());
},
);
}
}
在 _findFirstLocation 方法中,有以下调用数据库查询的方法。
  Future<List<Location>> findLocations() async {
final db = await database;

final List<Map<String, dynamic>> maps = await db.query(DatabaseConstants.LOCATION_TABLE_NAME);

return List.generate(maps.length, (i) {
Location location = Location(
locationId: maps[i][DatabaseConstants.COLUMN_NAME_LOCATION_ID],
street: maps[i][DatabaseConstants.COLUMN_NAME_STREET],
houseNumber: maps[i][DatabaseConstants.COLUMN_NAME_HOUSENUMBER],
zipCode: maps[i][DatabaseConstants.COLUMN_NAME_ZIP_CODE],
city: maps[i][DatabaseConstants.COLUMN_NAME_CITY],
);
return location;
});
}
因为我已经遇到了 await 问题,并且这些问题的原因是带有 lambda 表达式的 foreach(),所以我尝试了另一种类型的 for 循环作为替代:
  Future<List<Location>> findLocations() async {
final db = await database;

final List<Map<String, dynamic>> maps = await db.query(DatabaseConstants.LOCATION_TABLE_NAME);
final List<Location> locations = List();

for (int i = 0; i < maps.length; i++) {
var locationFromDatabase = maps[i];
Location location = Location(
locationId: maps[i][DatabaseConstants.COLUMN_NAME_LOCATION_ID],
street: maps[i][DatabaseConstants.COLUMN_NAME_STREET],
houseNumber: maps[i][DatabaseConstants.COLUMN_NAME_HOUSENUMBER],
zipCode: maps[i][DatabaseConstants.COLUMN_NAME_ZIP_CODE],
city: maps[i][DatabaseConstants.COLUMN_NAME_CITY],
);
locations.add(location);
}
return locations;
}
但在这两种情况下,应用程序都没有等待数据,我不明白原因。
先感谢您。
克里斯托弗

最佳答案

您的代码中有几个问题:
首先,如果您想“等待”,则在您希望流程等待时必须使用“等待”一词。您在 _findFirstLocation() 函数中执行此操作,但在调用它时并未执行此操作,因此,您应该像这样调用它:

await _findFirstLocation();
但即使这是不正确的,因为您试图阻止 UI 线程,这是完全禁止的(这会导致 UI 卡住,用户体验不佳)。
在这种情况下,您需要的是 FutureBuilder,您可以在其中指定后台进程运行时应该发生的情况、抛出错误时应该发生的情况以及返回结果时应该发生的情况。
最后,我建议你不要在 build() 方法中初始化变量,因为它可以被多次调用:
_useCaseManager = UseCaseManager.getInstance();
如果可能,我会将它移到类的主体中,如果不可能,则将其放入 initState() 方法中。

关于flutter - Flutter 中的 await 关键字不等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65480712/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com