Flutter StreamBuilder与FutureBuilder

问题描述 投票:18回答:2

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

  • 使用什么以及何时使用?
  • 他们打算执行哪些任务?
  • 他们每个人如何监听动态列表中的更改?
dart flutter
2个回答
33
投票

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

所以最后,他们的不同之处在于他们听的对象是如何工作的。

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

另一方面,Stream就像JS中的async Iterator。这可以被同化为可以随时间变化的值。它通常是Web套接字或事件(例如单击)的表示。通过听Stream,你将得到每个新的值,如果Stream有错误或完成。

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

Future不能听变量变化。这是一次性的回应。相反,你需要使用Stream


3
投票

FutureBuilder用于一次性响应,例如从Camera获取图像,从本机平台获取数据(如获取设备电池),获取文件引用,发出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++;
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.