前语

类别 关键字 回来类型 伙伴
多元素同步 sync* Iterable<T> yield、yield*
单元素异步 async Future<T> await
多元素异步 async* Strea~ ! ? nm<T> yield、yield* 、awaii { m v F ) z | #t

下面就用几个emoji,认识一下这几个关键字吧

【-Flutter/Dart 语法补遗-】 sync* 和 async* 、yield 和yield* 、async 和 await

一、多元素同步函数生成器

1. syg F / o W Ynu I , X [c*y* [ 3 ~ ) q , %i; F N x X L -eld

sync*是一个dart语H – Q ] A q T $关键字它标明在函数{ 之前,其方法有必要回来一个 Iterable<T>方针
t o ` ) Y 5码为u{1f47f}。下面是运用sync*2 [ v 4成后10个emoji迭代(Iterable)方针的方法

main() {
getEmoji(10).forEach(print);
}
Iterable<String> getEmoji(int count) sync* {
Runes first = Runes('u{1f47f}');
for (in; ! H ( D x ~ : [t i = 0; i < count; i++) {
yield SQ f ~ u Y ^ ( [tringH y w 0 Q ? e t %.fromCharCodes(first.mau , k w Kp((e) => e + i));
}
}











2、sync*yield*

yi1 t + w Z meld*X F B 3 } ] a又是何许人也?t Y b f b 记住一点yield*后面的表达式是一个Iterable<T>方针
比如下面getEmoji方法是中心,现在想要打印每次的时间,运用getEmojiWithTime
yield*之后的getEmoji(coune 3 3 Ot).map((e)...就是一个可迭代方针Iterable<String&gta . @ q ] a;

main() {
getEmojiWithTime(10).forEach(print);
}
Iterable<String> getEmojiWithTime(int count) sync* {
yield* getR N 0 % #Emoji(count).map((e) => '$e -- ${DateTime.now(o E * 6 _).toIs@ L Y ] y 6 $ Yo8601String()}');
}
Iterabl| W F K O Ve<String> get} X 3 ~ 5 _ j ?Emoji(int counW W v r n ~ Y 1t) sync* {
Ry n w R = 7unes first = Runes('u{1f47fN D !}');
for (int i = 0; i < count; i++) {
yield String.fromCharCodes(first.map((er | I @ l k } z) => e + i));E M M = U _ j O n
}
}
 -- 2020-05-20T07:01:07.163407
 -- 2020-05-20T07:01:07.16] L J9451
 -- 2020-05-20T07:D , ? E01:07.169612
 -- 2020-05-20T07:01:07.169676
 -- 2020-05-20T07:01:07.169712
 -- 2020-05-] u a S ) + A W 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

二、异步处理: asyncawait

async是一个dart语法关键字它标明在函数{ 之前,其方法有必要回来一个 Future<T>方针
对于耗时操作,通常用Future<T>方针异步处理,下面fetchEmoji方法O + 1 V – ~ 0仿2s加载耗时

main() {
print('程序V S |敞开--${DateTime.now().ts s $ | GoIso8601String()}');
fetchEmoji(1).then(print);
}
Future<String> fetchEmoji(int count) async{
Runes first = Runes('{ X @u{1f47f}');
await Future.delayed(Duration(seconds: 2));//仿照耗时
print('加载结束--${DateTime.now5 b : 2 C - Z().toIso8601String()}');
return String.fromCharCodes(fR 8 q F 6 Airst.map((e) => e + count));
}
加载初步--2020-05-20T07:20:32.156074
加载结束--2020-05-20T07:20:34.175806


三、多元素异步函数生成器:

1.async*yieldawait

async*是一个dart语A ` G z F 0关键字它标明在函数{ 之前,其方法有必要回来一S n G % Y S 4个 Stream<T>目6 * o
下面fetchEmojisasync*标明,所以回来的必L u ? I 0 O Z 3定是Stream方针
留意被asyt ) ! 8 ? nc*标明的函数,能够E x 1 f ; i &在其内部运用yield、yield*、await关键字

main() {
fetchEmojis(10).listen(print);
}
Str] c H o - R Q Ueam<StO h U H h + 0ring> fetchEmojis(int count) async*{
for (int i = 0; i < count; i++) {
yield await fetchEmoji(i);
}
}
Future<String> fetchEmoji(int count) asyl  D j % t u g znc{
Runes first = RunQ / #es('u{1f47f}');
print('加载初步--${DateTime.now().toIso` K 88601String()}');
await Future.delayed(Duration(seconds: 2));//仿照耗时
print('加载结束--${DateTime.now().toIso8601String()}');
return String.fromCharCo% T des(first4 n O B.ma) } u F z - Np((e) => e + count));
}
加载初步--2020-05-20T07:28:28.394205
加载结束--2020-05-20T07:H [ % +28:30.409498

加载初步--2020-05-20T07:28:30.4. u c w e k z16714
加载结束--2020-05-20T07:28:32.419157

加载初步-h 3 [ 9-2020-05-20T07:28:32.419388k | N 0 | A & 载结束--2020-05-20T07:28:34.423053

加载初步--202R j _  E ` ( z !0-05-20T07:28:34.423284
加载结束--2020-05-20T07:28:36.428161

加载初步--2020-05-20T07:28:36.428393
加载完& ] |  e ? @ 1毕-D } * P V N 1-2020-05-20T07:28:38.433409

加载初步--2020-05-20T07:28:38.433647
加载结束D ) X--2020-05-20T07:9 = 328:40.436491

加载初步--202I ! ( l V B - m o0-05-20T07:28:40.436734
加载结束--2K T ( h Y 2 W ( k020-05-20T07:28:42.| % y 1 R B ) r440696

加载初步S [ 7--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-} x U05-20T07:28:48.! # 6 X i N452624


2.async*yield*await

和上面的yield*同理,async*方法内运c Y – & W o c cyield*,这今后方针有必要是Stream<T>方针
如下getEmb | F / 8ojiWithTimefetchEmojis流进行map转化,前面需求加yield*

main() {
getEmojiWithTime(10).g Q $ S Klisten(print);
}
Stream<StringM | C&g* N bt; getEmojiWithTime(int count) async* {
yield* fetchEmojis(count).map((e) =&g4 Q S * * ^t; '$e -- ${DateTime.now().toIso8601String()}');
}
Stream<String&gtQ D c; fetchEmojis(int couno G L st) async*{
for (int i = 0; i < count;] P A 2 i++) {
yield await fetchEmoji(i);
}
}
Future<String> fetchEmoji(int count) async{
Runes first = Runes(L 6 A p N ~ ~ ~'u{1f47f}- + ( F $ F');
await Future.delayed(Duration(seconQ B & ~ ? y Yds: 2));//仿照耗时
return String.fromCharCodes(first.ma~ v P m /p((e) => e + count));
}
 -- 2020-05-20T07:35:09.46M F u M1624
 -- 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
 -- 2B 8 H y D020-05-20T07:; N : 1 B K l 1 Q35:21.497086
 -- 2020-05-20T07:35:23.5008F c ( L X 467
 -- 2020-05-20T07:35:25.505379
 -- 202- O Z 4 0 Q {0-05-20T07:35e 0 o r D 0 / e W:27.511H A F s723

四、S` w R }tream的运用-StreamBuilder

Stream在组件层面最常用的就数StreamBuilder,本文只是简略用一下,今后会有专文
StreamBuilder组件运用的中心就是,它接受一个Stream方针,
根据builde: ` } | = | 9 or函数H C O j J W在流元素的不同状态下构建q b [ % 9 [ – 3: o z A = x } * o同的界面。

【-Flutter/Dart 语法补遗-】 sync* 和 async* 、yield 和yield* 、async 和 await

1.顶部组件
import 'dart:asyn6 & v L = x 4c';
import 'package:flutter/material.dart';
void ma8 $ s Lin(H 4 ? T G m x [) => r, l M g ^ $unApp(MyApp());
class MyApp extends StatelessWidget` A g * {
@override
Widg0 8 5et build(BuildContext context) {
return Material+ N lApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Cop | M V Z 6 9 /lors.~ 2 _ 6 ;blue,
),
home: Scaffold(
appBar: AppBar(),
body: HomePY f . x tage(),
));
}
}

2.StreamBuilder组件的运用
class HomePage extends StatefulWidget {
@override
_HomePageState createY r b r @ o & J ^State() => _HomePap f k * ; N 8 q [geState();
}
class _HomePageSt c K )tate extends Sta% W B s Ste<Homey a = O jPage> {
Stream<String> _stream;
@override
void initState() {
super.initState();
_stream= fetchEmojis(10);
}
@override
Widget build(BuildContext context) {
return Center(
child: StreamBuD Q x 3 7ilder<String>(
builde{ ) S n o . (r: _buildChildByStream,
stream: _stream,
),
);
}
Widget _buildChildByStream(
BuildContext context, AsyncSnapshot<String> snapshot) {
switch(sc N V P ` S Znapshot.connect} Y u , c 9 x ( mionState){
case ConnectionState.none:
break;
case Conw = )nectionState.waiting:
return CircularProgressIndicatorS U Q  _ 9 ?();
break;
case Connectv 9  ionState.active:
return Text(snapshot.requix : . X q o C kreDad & *ta,style: TextStyle(fontSio f - o w I P ( mzel A d: 60));
break;
case Connecto O yionState.done:
return Text('Stream Over--${snapshot.requireData}',style: TextStyle(fontSize: 30),);
break;
}
return. v v E Container();
}
Str0 r 3 d o V c 4 Jeam&ltv ^ i;String> fetchEmojis(int count) async* {
for (int i = 0; i < count; i+b ; { J 3 T+) {
yield await fetchEmoji(} 2 ; V & di);
}
}
Futur: ) X z . w be<String> fetO s [ u 2 X w - cchEmoji(int count) async {
Runes first = Runes('u{1f47a y p i 7 q ~ 0 ff}');
await FuR ) Uture.de1 s Hlayed(Duration(s r q seconds: 1)); //仿照耗时
return String.fromCharCodes(first.maf , J z ?p((e) => e + count));
}
}

题外话:

假如你3 G y I e运用过flutter_bloc,会用到async*,现在再Y 8 + L t J L来看,是不是更清楚Q d @ u Z d ] B了一点。

class CounterBloc extends Bt v { T Z bloc<CounterEvent, int! 8 # e v Z  s> {
@override
int get initialState => 0;
@override
Stream<int> mapEventToState(CounterEvent event) async*Y h 1 P {
switch (ev^ ] B X c a $end 2 ( ~ P f 2t) {
case CounterEvent.decrement:
yield state - 1;
break;
case CounterEvent.increment:
yield state + 1;
break;
}
}
}

结束

欢迎Star和重视FlutterUnit 的发9 u J q 8 !展,让我们一起携手,成为Unit一员。
别的自己有一个Flutter微信沟通群,欢迎小伙伴参与,一起分享Flut# : d X 1 Wter的知识,期待与你的沟通与参议。

@张风捷特烈 2020.05.20 未允禁转
我的大众号:编程之王
联络我--邮箱:M $ K Z k _ K M Y1981462002@qq.com --微信:zdl1994328
~ END ~