StreamBuilder
和FutureBuilder
之间的主要区别是什么?
StreamBuilder
和FutureBuilder
都有相同的行为:他们听取各自对象的变化。并在收到新值通知时触发新构建。
所以最后,他们的不同之处在于他们听的对象是如何工作的。
Future
就像JS中的Promise
或c#中的Task
。它们是异步请求的表示。 Futures
只有一个回应。 Future
的一个常见用法是处理http调用。你可以在Future
上听到的是它的状态。无论是完成,成功完成还是出错。但就是这样。
另一方面,Stream
就像JS中的async Iterator
。这可以被同化为可以随时间变化的值。它通常是Web套接字或事件(例如单击)的表示。通过听Stream
,你将得到每个新的值,如果Stream
有错误或完成。
他们每个人如何监听动态列表中的更改?
Future
不能听变量变化。这是一次性的回应。相反,你需要使用Stream
。
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++;
}
}
}