前言
类别 | 关键字 | 返回类型 | 搭档 |
---|---|---|---|
多元素同步 | sync* | Iterable<T> |
yield、yield* |
单元素异步 | async | Future<T> |
await |
多元素异步 | async* | Stream<T> |
yield、yield* 、await |
下面就用几个emoji,认识一下这几个关键字吧git
1、多元素同步函数生成器
1. sync*
和 yield
sync*
是一个dart语法关键字
。它标注在函数{ 以前,其方法必须返回一个 Iterable<T>对象
github
👿 的码为\u{1f47f}
。下面是使用sync*
生成后10个emoji迭代(Iterable)对象
的方法编程
main() {
getEmoji(10).forEach(print);
}
Iterable<String> getEmoji(int count) sync* {
Runes first = Runes('\u{1f47f}');
for (int i = 0; i < count; i++) {
yield String.fromCharCodes(first.map((e) => e + i));
}
}
复制代码
👿
💀
💁
💂
💃
💄
💅
💆
💇
💈
复制代码
二、sync*
和 yield*
yield*
又是何许人也? 记住一点yield*
后面的表达式是一个Iterable<T>对象
微信
好比下面getEmoji
方法是核心,如今想要打印每次的时间,使用getEmojiWithTime
yield*
以后的getEmoji(count).map((e)...
即是一个可迭代对象Iterable<String>
markdown
main() {
getEmojiWithTime(10).forEach(print);
}
Iterable<String> getEmojiWithTime(int count) sync* {
yield* getEmoji(count).map((e) => '$e -- ${DateTime.now().toIso8601String()}');
}
Iterable<String> getEmoji(int count) sync* {
Runes first = Runes('\u{1f47f}');
for (int i = 0; i < count; i++) {
yield String.fromCharCodes(first.map((e) => e + i));
}
}
复制代码
👿 -- 2020-05-20T07:01:07.163407
💀 -- 2020-05-20T07:01:07.169451
💁 -- 2020-05-20T07:01:07.169612
💂 -- 2020-05-20T07:01:07.169676
💃 -- 2020-05-20T07:01:07.169712
💄 -- 2020-05-20T07:01:07.169737
💅 -- 2020-05-20T07:01:07.169760
💆 -- 2020-05-20T07:01:07.169789
💇 -- 2020-05-20T07:01:07.169812
💈 -- 2020-05-20T07:01:07.169832
复制代码
2、异步处理: async
和await
async
是一个dart语法关键字
。它标注在函数{ 以前,其方法必须返回一个 Future<T>对象
app
对于耗时操做,一般用Future<T>
对象异步处理,下面fetchEmoji方法
模拟2s加载耗时less
main() {
print('程序开启--${DateTime.now().toIso8601String()}');
fetchEmoji(1).then(print);
}
Future<String> fetchEmoji(int count) async{
Runes first = Runes('\u{1f47f}');
await Future.delayed(Duration(seconds: 2));//模拟耗时
print('加载结束--${DateTime.now().toIso8601String()}');
return String.fromCharCodes(first.map((e) => e + count));
}
复制代码
加载开始--2020-05-20T07:20:32.156074
加载结束--2020-05-20T07:20:34.175806
💀
复制代码
3、多元素异步函数生成器:
1.async*
和yield
、await
async*
是一个dart语法关键字
。它标注在函数{ 以前,其方法必须返回一个 Stream<T>对象
异步
下面fetchEmojis
被async*
标注,因此返回的必然是Stream
对象
注意被async*
标注的函数,能够在其内部使用yield、yield*、await
关键字async
main() {
fetchEmojis(10).listen(print);
}
Stream<String> fetchEmojis(int count) async*{
for (int i = 0; i < count; i++) {
yield await fetchEmoji(i);
}
}
Future<String> fetchEmoji(int count) async{
Runes first = Runes('\u{1f47f}');
print('加载开始--${DateTime.now().toIso8601String()}');
await Future.delayed(Duration(seconds: 2));//模拟耗时
print('加载结束--${DateTime.now().toIso8601String()}');
return String.fromCharCodes(first.map((e) => e + count));
}
复制代码
加载开始--2020-05-20T07:28:28.394205
加载结束--2020-05-20T07:28:30.409498
👿
加载开始--2020-05-20T07:28:30.416714
加载结束--2020-05-20T07:28:32.419157
💀
加载开始--2020-05-20T07:28:32.419388
加载结束--2020-05-20T07:28:34.423053
💁
加载开始--2020-05-20T07:28:34.423284
加载结束--2020-05-20T07:28:36.428161
💂
加载开始--2020-05-20T07:28:36.428393
加载结束--2020-05-20T07:28:38.433409
💃
加载开始--2020-05-20T07:28:38.433647
加载结束--2020-05-20T07:28:40.436491
💄
加载开始--2020-05-20T07:28:40.436734
加载结束--2020-05-20T07:28:42.440696
💅
加载开始--2020-05-20T07:28:42.441255
加载结束--2020-05-20T07:28:44.445558
💆
加载开始--2020-05-20T07:28:44.445801
加载结束--2020-05-20T07:28:46.448190
💇
加载开始--2020-05-20T07:28:46.448432
加载结束--2020-05-20T07:28:48.452624
💈
复制代码
2.async*
和yield*
、await
和上面的
yield*
同理,async*
方法内使用yield*
,其后对象必须是Stream<T>
对象ide
以下getEmojiWithTime
对fetchEmojis
流进行map转换,前面须要加yield*
main() {
getEmojiWithTime(10).listen(print);
}
Stream<String> getEmojiWithTime(int count) async* {
yield* fetchEmojis(count).map((e) => '$e -- ${DateTime.now().toIso8601String()}');
}
Stream<String> fetchEmojis(int count) async*{
for (int i = 0; i < count; i++) {
yield await fetchEmoji(i);
}
}
Future<String> fetchEmoji(int count) async{
Runes first = Runes('\u{1f47f}');
await Future.delayed(Duration(seconds: 2));//模拟耗时
return String.fromCharCodes(first.map((e) => e + count));
}
复制代码
👿 -- 2020-05-20T07:35:09.461624
💀 -- 2020-05-20T07:35:11.471223
💁 -- 2020-05-20T07:35:13.476712
💂 -- 2020-05-20T07:35:15.482848
💃 -- 2020-05-20T07:35:17.489429
💄 -- 2020-05-20T07:35:19.491214
💅 -- 2020-05-20T07:35:21.497086
💆 -- 2020-05-20T07:35:23.500867
💇 -- 2020-05-20T07:35:25.505379
💈 -- 2020-05-20T07:35:27.511723
复制代码
4、Stream的使用-StreamBuilder
Stream在组件层面最经常使用的就数
StreamBuilder
,本文只是简单用一下,之后会有专文
StreamBuilder
组件使用的核心就是,它接受一个Stream对象
,
根据builder函数
在流元素的不一样状态下构建不一样的界面。
1.顶部组件
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(),
body: HomePage(),
));
}
}
复制代码
2.StreamBuilder组件的使用
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Stream<String> _stream;
@override
void initState() {
super.initState();
_stream= fetchEmojis(10);
}
@override
Widget build(BuildContext context) {
return Center(
child: StreamBuilder<String>(
builder: _buildChildByStream,
stream: _stream,
),
);
}
Widget _buildChildByStream(
BuildContext context, AsyncSnapshot<String> snapshot) {
switch(snapshot.connectionState){
case ConnectionState.none:
break;
case ConnectionState.waiting:
return CircularProgressIndicator();
break;
case ConnectionState.active:
return Text(snapshot.requireData,style: TextStyle(fontSize: 60));
break;
case ConnectionState.done:
return Text('Stream Over--${snapshot.requireData}',style: TextStyle(fontSize: 30),);
break;
}
return Container();
}
Stream<String> fetchEmojis(int count) async* {
for (int i = 0; i < count; i++) {
yield await fetchEmoji(i);
}
}
Future<String> fetchEmoji(int count) async {
Runes first = Runes('\u{1f47f}');
await Future.delayed(Duration(seconds: 1)); //模拟耗时
return String.fromCharCodes(first.map((e) => e + count));
}
}
复制代码
题外话:
若是你使用过
flutter_bloc
,会用到async*
,如今再来看,是否是更清楚了一点。
class CounterBloc extends Bloc<CounterEvent, int> {
@override
int get initialState => 0;
@override
Stream<int> mapEventToState(CounterEvent event) async* {
switch (event) {
case CounterEvent.decrement:
yield state - 1;
break;
case CounterEvent.increment:
yield state + 1;
break;
}
}
}
复制代码
尾声
欢迎Star和关注FlutterUnit 的发展,让咱们一块儿携手,成为Unit一员。
另外本人有一个Flutter微信交流群,欢迎小伙伴加入,共同分享Flutter的知识,期待与你的交流与切磋。
@张风捷特烈 2020.05.20 未允禁转
个人公众号:编程之王
联系我--邮箱:1981462002@qq.com --微信:zdl1994328
~ END ~
本文同步分享在 博客“张风捷特烈”(JueJin)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。