颤振:从UI调用异步代码的最佳实践

Won*_*mmy 9 async-await dart flutter

我正在开发一个Flutter应用程序,但想知道从UI调用异步代码时我该怎么办 - 让我们说一下UI小部件的构建方法.

例如,我的应用通过服务类连接Firebase,该服务类使用Async-Await样式从Firebase获取记录.使用await确保我的服务类的方法将在返回UI端之前完成记录检索.

但是,由于服务类的方法被标记为异步,因此在服务类的方法完成之前,它会立即向调用UI小部件返回Future,并且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
    .....
    .....
Run Code Online (Sandbox Code Playgroud)

很抱歉,如果我的描述不清楚,欢迎任何建议.

吉米

azi*_*iza 23

在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
},);
  }
Run Code Online (Sandbox Code Playgroud)

示例StreamBuilder:

class Database {

  DatabaseReference _refProfile = FirebaseDatabase.instance.reference().child(
      "profiles");

  getProfiles() => _refProfile.onValue; }
Run Code Online (Sandbox Code Playgroud)

.............

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
}
Run Code Online (Sandbox Code Playgroud)

值得一提的是

FutureBuilder当你想为更好地利用获取的一些数据曾经并不在乎有一致的连接或跟踪数据中的任何改变.

StreamBuilder另一方面,虽然可以让您继续监听数据,但您可以根据数据中的任何更新来更新UI的状态.

  • 我编写了答案,包括StreamBuilder的示例,以及文档的链接. (2认同)
  • @Wonderjimmy这是我的坏,我本来应该更清楚,你永远不想在Scaffold级别上做FutureBuilder,而是在body属性中做.这样你的appbar,抽屉,FAB,tabs..etc将正常加载,只有包含内容的主体才会加载. (2认同)