【问题标题】:Flutter StreamBuilder vs FutureBuilderFlutter StreamBuilder 与 FutureBuilder
【发布时间】:2018-11-23 11:10:55
【问题描述】:

StreamBuilderFutureBuilder 之间的主要区别是什么。

  • 使用什么以及何时使用?

  • 他们打算执行什么任务?

  • 他们每个人如何监听动态列表中的变化?

【问题讨论】:

标签: flutter dart flutter-futurebuilder flutter-streambuilder


【解决方案1】:

StreamBuilderFutureBuilder 具有相同的行为:它们监听各自对象的变化。并在收到通知时触发新构建 新的价值。

所以说到底,他们的区别在于他们所听的对象是如何工作的。

Future 类似于 JS 中的 Promise 或 c# 中的 Task。它们是异步请求的表示。 Futures 有一个且只有一个响应。 Future 的一个常见用法是处理 HTTP 调用。你可以在Future 上听到的是它的状态。无论是完成、成功完成还是出现错误。但就是这样。

另一方面,Stream 就像 JS 中的异步 Iterator。这可以被同化为一个可以随时间变化的值。它通常是网络套接字或事件(如点击)的表示。通过收听Stream,您将获得每个新值以及Stream 是否有错误或已完成。

他们每个人如何监听动态列表中的变化?

Future 无法监听变量更改。这是一次性响应。相反,您需要使用Stream

【讨论】:

    【解决方案2】:

    FutureBuilder 用于一次性响应,例如从相机中获取图像,从原生平台获取一次数据(例如获取设备电池),获取文件引用,发出 http 请求等。

    另一方面,StreamBuilder 用于多次获取某些数据,例如监听位置更新、播放音乐、秒表等。


    这是提及这两种情况的完整示例。

    FutureBuilder 求解平方值并在 5 秒后返回结果,直到我们向用户显示进度指示器。

    StreamBuilder 显示一个秒表,每秒将_count 的值增加 1。

    void main() => runApp(MaterialApp(home: HomePage()));
    
    class HomePage extends StatefulWidget {
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      int _count = 0; // used by StreamBuilder
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              _buildFutureBuilder(),
              SizedBox(height: 24),
              _buildStreamBuilder(),
            ],
          ),
        );
      }
    
      // constructing FutureBuilder
      Widget _buildFutureBuilder() {
        return Center(
          child: FutureBuilder<int>(
            future: _calculateSquare(10),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done)
                return Text("Square = ${snapshot.data}");
    
              return CircularProgressIndicator();
            },
          ),
        );
      }
    
      // used by FutureBuilder
      Future<int> _calculateSquare(int num) async {
        await Future.delayed(Duration(seconds: 5));
        return num * num;
      }
    
      // constructing StreamBuilder
      Widget _buildStreamBuilder() {
        return Center(
          child: StreamBuilder<int>(
            stream: _stopwatch(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.active)
                return Text("Stopwatch = ${snapshot.data}");
    
              return CircularProgressIndicator();
            },
          ),
        );
      }
    
      // used by StreamBuilder
      Stream<int> _stopwatch() async* {
        while (true) {
          await Future.delayed(Duration(seconds: 1));
          yield _count++;
        }
      }
    }
    

    【讨论】:

    • 那么,如果我想从 API 或 URL/HTTP 请求中实时更新数据,我应该使用哪一个?
    • StreamBuilder
    【解决方案3】:

    我发现有时现实世界的类比对于解释/记住概念很有效。这是一个 - 它并不完美,但它对我有帮助。

    想象一下,您身处其中一家现代化的寿司餐厅,您的房间里有一条腰带,上面挂着寿司船。你只是坐下来等一个人经过,抓住它吃。但它们也允许您订购。

    一个Future就像是一个代币,上面有一个数字,当你点外卖时他们会给你;您提出了请求,但结果尚未准备好,但您有一个占位符。当结果准备好后,您会收到回电(外卖柜台上方的数字板会显示您的号码,或者他们会喊出来)-您现在可以进去拿食物(结果)取出。

    溪流就像那条背着小寿司碗的腰带。通过坐在那张桌子旁,您已经“订阅”了流。您不知道下一艘寿司船什么时候到达 - 但是当厨师(消息源)将其放入流(传送带)时,订阅者就会收到它。需要注意的重要一点是它们是异步到达的(您不知道下一条船/消息何时到达)但它们会按顺序到达(即,如果厨师按顺序将三种寿司放在腰带上——您会看到它们以相同的顺序从您身边而来)

    从编码的角度来看——Futures 和 Streams 都可以帮助您处理异步(事情不会立即发生,并且您不知道何时在您编写完代码后会得到结果请求)。

    不同之处在于,Futures 是关于一次性请求/响应(我问,有延迟,我收到通知说我的 Future 已准备好收集,我已经完成了!)而 Streams 是一个连续的系列对单个请求的响应(我问,有延迟,然后我不断收到响应,直到流干涸或我决定关闭它并走开)。

    希望对您有所帮助。

    【讨论】:

      【解决方案4】:

      FutureBuilder

      它只有一个响应。 Flutter Future 的一个非常常见的用法是在 http 调用期间。你可以用 Future 做的就是监听它的状态,即当它通过 Future 完成获取数据后完成或出错时

      对于 FutureBuilder,我们在 Flutter 文档中阅读了以下警告:

      未来一定是更早得到的,...... 如果未来与 FutureBuilder 同时创建, 那么每次FutureBuilder的父级重建时,异步任务都会重新启动。

      在许多教程中,我看到类似这样的内容:

      FutureBuilder(
          future : foo.asyncMethod();
          builder : (context, snapshot){
      
          }
      )
      

      这不好,因为每次调用构建过程都会调用异步方法并调用 FutureBuilder 的构建器。

      如果您的用例只是获取数据并显示它,例如来自 API 的类的课程总数。然后你可以使用FutureBuilder

      StreamBuilder

      另一方面,流是迭代器,它可以吸收不同的值,这些值会随着时间而改变。通过使用 Stream,您将获得每个新值,并且如果它有一些错误或者它完成了成功消息

      如果在您使用该应用程序时,数据每秒或每分钟更新一次,例如博客中即将发布的帖子,或增加博客上的 cmets 或增加博客上的点赞数。它以一定的时间间隔异步更新,在这种情况下StreamBuilder 是最好的选择。

      【讨论】:

        猜你喜欢
        • 2020-11-09
        • 2021-07-19
        • 2022-08-19
        • 1970-01-01
        • 2019-03-30
        • 1970-01-01
        • 2020-05-28
        • 1970-01-01
        • 2021-06-24
        相关资源
        最近更新 更多