StreamBuilder和 FutureBuilder的主要区别是什么。
StreamBuilder
FutureBuilder
使用什么和什么时候使用?
它们打算执行哪些任务?
它们如何监听动态列表中的更改?
StreamBuilder和 FutureBuilder具有相同的行为: 它们监听各自对象上的更改。并在接到通知时触发新的构建 一个新的价值。
所以最后,他们的不同之处在于他们听到的对象是如何工作的。
Future类似于 JS 中的 Promise或 c # 中的 Task。它们是异步请求的表示形式。Futures只有一个响应。Future的一个常见用法是处理 HTTP 调用。你可以在 Future上听到的是它的状态。无论是完成了,成功完成了,还是出了差错。但仅此而已。
Future
Promise
Task
Futures
另一方面,Stream与 JS 中的异步 Iterator相似。这可以被同化为一个随时间变化的值。它通常是 Web 套接字或事件(如点击)的表示。通过收听 Stream,您将得到每个新值,也如果 Stream有一个错误或完成。
Stream
Iterator
Future无法监听变量更改。这是一次性响应。相反,您需要使用 Stream。
FutureBuilder用于一次性响应,如从相机获取图像、从本地平台获取一次性数据(如获取设备电池)、获取文件引用、发出 http 请求等。
另一方面,StreamBuilder用于不止一次地获取某些数据,如收听位置更新、播放音乐、秒表等。
下面是提到这两种情况的完整例子。
FutureBuilder解决一个平方值并在5秒钟后返回结果,直到我们向用户显示进度指示器。
StreamBuilder显示一个秒表,每秒钟将 _count值递增1。
_count
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++; } } }
我发现有时现实世界的类比对于解释/记忆概念很有效。这里有一个-它不是完美的,但它帮助我。
想象一下你在一家现代的寿司店里,你有一条带子绕着房间转,上面有寿司船。你只要坐下来,等一个人走过,抓起来吃。但是他们也允许你命令执行。
未来就像一个标记,上面有一个数字,当你点外卖时,他们会给你这个数字; 你提出了请求,但是结果还没有准备好,但是你有一个占位符。当结果准备好了,你会得到一个回复(外卖柜台上方的数字显示板显示你的号码,或者他们喊出来)——你现在可以进去拿你的食物(结果)外卖。
溪流就像那个带着小寿司碗的腰带。坐在那张桌子旁,你已经“订阅”了这条流。你不知道下一艘寿司船什么时候到达——但是当厨师(消息来源)把它放在流(带)中时,订阅者就会收到它。需要注意的重要一点是,它们是异步到达的(你不知道下一条船/信息什么时候到达) ,但它们会按顺序到达(也就是说,如果厨师把三种类型的寿司按某种顺序放在腰带上——你会看到它们以同样的顺序从你身边经过)
从编码的角度来看—— Futures 和 Streams 都可以帮助您处理异步(在这种情况下,事情不会立即发生,而且您不知道 什么时候,在您发出请求之后您将得到一个结果)。
不同之处在于 Futures 是关于一次性请求/响应(我问,有一个延迟,我得到一个通知,说我的 Future 已经准备好收集了,然后我就完成了!)而 Streams 是对单个请求的一系列连续响应(我问,有一个延迟,然后我继续得到响应,直到流干涸或者我决定关闭它并离开)。
希望能帮上忙。
FutureBuilder 和 StreamBuilder的行为类似: 它们监听各自对象中的更改。为了响应更改值通知,将触发一个新的构建。
最终,区别在于它们如何监听异步调用。
未来建设者
对此只有一种反应。期货通常用于 http 呼叫。Future 可以用来监听状态,例如,当它完成获取数据或出现错误时。
例如链接 给你。
与流相反,流是迭代器,可以吸收不同的值,这些值将随着时间的推移而变化。Stream 将返回每个新值以及错误消息或成功消息(如果有的话)。
结论
以下数据可能有助于你更好地理解上述内容:
如果您的用例只是获取数据并显示它,比如来自 API 的类的总课程数。然后你就可以使用 FutureBuilder 了。 如果在你使用应用程序的时候,数据每秒或每分钟更新一次,比如在博客中即将发表的文章,或者在博客上增加评论,或者在博客上增加喜欢,会怎么样呢。它在一定时间间隔内异步更新,在这种情况下 StreamBuilder 是最佳选择。 根据用例,您可以决定使用哪一个。
这里有一个完整的例子提到了这两种情况。 FutureBuilder 解决一个平方值并在5秒后返回结果,直到我们向用户显示一个进度指示器。
StreamBuilder 显示一个秒表,其中 _ count 值每秒递增1。