Flutter:从UI调用异步代码的最佳做法 [英] Flutter: Best Practices of Calling Async Code from UI

查看:93
本文介绍了Flutter:从UI调用异步代码的最佳做法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发Flutter应用程序,但想知道从UI调用异步代码时应该怎么做-假设UI小部件的构建方法.

I am developing a Flutter app but wondering what should I do when calling async code from UI - let's say the build method of a UI widget.

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

For example, my app connects Firebase through a service class, which uses Async-Await style to grab records from Firebase. Using await ensures my service class's method will complete records retrieval before returning to the UI side.

但是,由于服务类的方法被标记为异步,因此它将在服务类的方法完成之前立即将Future返回给调用的UI小部件,并且UI代码保持运行.

However, since the service class's method is marked as async, it returns a Future immediately to the calling UI widget and the UI code keeps running, before the service class's method is completed.

是的,我可以为"then()"回调编写代码以处理检索到的记录,但是小部件内部随后的其他代码又取决于异步调用的结果呢?这是否意味着我需要将所有内容都嵌入"then()"子句中,并避免在返回Future的方法调用之后添加任何执行步骤?对于这种使用模型有什么建议的模式吗?

Yes I can write codes for the "then()" callback to handle the retrieved records, but what about other codes inside the widget that follow, and depend on the result of the async call? Does it mean I need to embed everything inside the "then()" clause and avoid adding any execution steps after a method call that returns a Future? Any suggested pattern for such usage model?

@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
    .....
    .....

很抱歉,如果我在此处的描述不够清楚,欢迎您提出任何建议.

Sorry if my description here is lack of clarity, any advice is much welcome.

吉米

推荐答案

在Flutter中,有一些小部件可以帮助您无缝执行此操作(例如,

In Flutter there are widgets that can help you do this seamlessly (e.g, FutureBuilder , StreamBuilder) and you can control what to be rendered based on their resolution.

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当您想要一次一次 并且不关心保持一致的连接或跟踪数据中的任何更改时,更适合使用.

FutureBuilder is better used when you want to fetch some data once and do not care of having consistent connection or tracking any changes in the data.

另一方面,StreamBuilder使您可以继续收听数据,并且可以根据数据中的任何更新来更新UI的状态.

While StreamBuilder , on the other hand, enables you to keep listening to the data and you can update the state of the UI according to any update in the data.

这篇关于Flutter:从UI调用异步代码的最佳做法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆