Flutter:从UI调用异步代码的最佳做法
问题内容:
我正在开发Flutter应用程序,但想知道从UI调用异步代码时应该怎么做-假设UI小部件的构建方法。
例如,我的应用程序通过服务类连接Firebase,该服务类使用Async-
Await样式从Firebase抓取记录。使用await可确保我的服务类的方法在返回UI端之前将完成记录检索。
但是,由于服务类的方法被标记为异步,因此它将在服务类的方法完成之前立即将Future返回给调用UI小部件,并且UI代码保持运行。
是的,我可以为“ then()”回调编写代码以处理检索到的记录,但是小部件内随后的其他代码又取决于异步调用的结果呢?这是否意味着我需要将所有内容都嵌入“
then()”子句中,并避免在返回Future的方法调用之后添加任何执行步骤?对于这种使用模型有什么建议的模式吗?
@override
Widget build(BuildContext context) {
RealtimeDatabase.getData() // my service class
.then((onValue) {
..... // do something after the async call is completed
}
..... // do something immediately before the async call is done
class RealtimeDatabase {
Future<String> getData() async {
DataSnapshot dataSnapshot = await FirebaseDatabase.instance.reference().orderByKey().once(); // will wait until completed
.....
.....
抱歉,如果我的描述不够清楚,欢迎提供任何建议。
吉米
问题答案:
在Flutter中,有一些小部件可以帮助您无缝执行此操作(例如FutureBuilder
,StreamBuilder
),并且您可以根据其分辨率控制要呈现的内容。
范例FutureBuilder
:
Widget build(BuildContext context) {
return new FutureBuilder(
future: FirebaseDatabase.instance.reference().child("node"),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot.hasData? new Scaffold(
///start building your widget tree
):new CircularProgressIndicator(); ///load until snapshot.hasData resolves to true
},);
}
示例StreamBuilder
:
class Database {
DatabaseReference _refProfile = FirebaseDatabase.instance.reference().child(
"profiles");
getProfiles() => _refProfile.onValue; }
.............
Widget build(BuildContext context) {
return new StreamBuilder<Event>(
stream: _database.getProfiles(), //_database = new Database()
builder: (BuildContext context, AsyncSnapshot<Event> event) {
return event.hasData?new Scaffold(
///build your widget tree
):new CircularProgressIndicator();
/// place holder
}
值得一提的是
FutureBuilder
如果您希望 一次 获取 一些数据并且不关心保持一致的连接或跟踪数据中的任何更改,则最好使用。 __
而StreamBuilder
另一方面,通过,您可以继续收听数据,并且可以根据数据中的任何更新来更新UI的状态。