Flutter 颤振StreamBuilder vs FutureBuilder

Flutter 颤振StreamBuilder vs FutureBuilder,flutter,dart,flutter-futurebuilder,flutter-streambuilder,Flutter,Dart,Flutter Futurebuilder,Flutter Streambuilder,StreamBuilder和FutureBuilder之间的主要区别是什么 使用什么以及何时使用 他们打算执行哪些任务 它们如何侦听动态列表中的更改 StreamBuilder和FutureBuilder都有相同的行为:它们监听各自对象上的更改。并在收到通知时触发新生成 具有新的价值 所以最终,他们的区别在于他们所听的对象是如何工作的 Future就像JS中的Promise或者c#中的Task。它们是异步请求的表示期货只有一个响应。Future的一个常见用法是处理HTTP调用。在未来上,您可以

StreamBuilder
FutureBuilder
之间的主要区别是什么

  • 使用什么以及何时使用

  • 他们打算执行哪些任务

  • 它们如何侦听动态列表中的更改


    • StreamBuilder和
      FutureBuilder
      都有相同的行为:它们监听各自对象上的更改。并在收到通知时触发新生成 具有新的价值

      所以最终,他们的区别在于他们所听的对象是如何工作的

      Future
      就像JS中的
      Promise
      或者c#中的
      Task
      。它们是异步请求的表示<代码>期货只有一个响应。
      Future
      的一个常见用法是处理HTTP调用。在
      未来
      上,您可以听到的是它的状态。不管它是成功完成的,还是有错误的。但就是这样

      另一方面,流类似于JS中的异步迭代器。这可以转化为一个随时间变化的值。它通常是web套接字或事件(如单击)的表示。通过收听
      ,您将获得每个新值,以及
      是否有错误或已完成

      它们如何侦听动态列表中的更改


      Future
      无法侦听变量更改。这是一次性的回应。相反,您需要使用

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

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


      下面是提到这两种情况的完整示例


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

      StreamBuilder
      显示秒表,每秒递增
      \u 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++;
          }
        }
      }
      
      void main()=>runApp(MaterialApp(home:HomePage());
      类主页扩展了StatefulWidget{
      @凌驾
      _HomePageState createState()=>\u HomePageState();
      }
      类_HomePageState扩展状态{
      int _count=0;//由StreamBuilder使用
      @凌驾
      小部件构建(构建上下文){
      返回脚手架(
      正文:专栏(
      mainAxisAlignment:mainAxisAlignment.center,
      儿童:[
      _buildFutureBuilder(),
      尺寸箱(高度:24),
      _buildStreamBuilder(),
      ],
      ),
      );
      }
      //构建未来建设者
      Widget_buildFutureBuilder(){
      返回中心(
      孩子:未来建设者(
      未来:_calculateSquare(10),
      生成器:(上下文,快照){
      if(snapshot.connectionState==connectionState.done)
      返回文本(“Square=${snapshot.data}”);
      返回循环ProgressIndicator();
      },
      ),
      );
      }
      //由FutureBuilder使用
      Future\u calculateSquare(int num)异步{
      等待未来。延迟(持续时间(秒:5));
      返回num*num;
      }
      //构建StreamBuilder
      小部件_buildStreamBuilder(){
      返回中心(
      孩子:StreamBuilder(
      流:_stopwatch(),
      生成器:(上下文,快照){
      if(snapshot.connectionState==connectionState.active)
      返回文本(“秒表=${snapshot.data}”);
      返回循环ProgressIndicator();
      },
      ),
      );
      }
      //由StreamBuilder使用
      流_stopwatch()异步*{
      while(true){
      等待未来。延迟(持续时间(秒:1));
      产量_计数++;
      }
      }
      }
      
      我发现,有时现实世界中的类比可以很好地解释/记忆概念。这里有一个-它不是完美的,但它帮助了我

      假设你在一家现代化的寿司餐厅,那里有一条腰带绕着房间转,上面有寿司船。你只要坐下来等一个人走过,抓住它吃。但它们也允许您命令执行

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

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

      从编码的角度来看——未来和流都可以帮助您处理异步(在异步中,事情不会立即发生,您不知道何时发出请求后会得到结果)

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


      希望这能有所帮助。

      FutureBuilder

      它只有一个响应。颤振未来的一个非常常见的用法是在
      FutureBuilder(
          future : foo.asyncMethod();
          builder : (context, snapshot){
      
          }
      )