事件循环Event Loop机制
Future就像是盒子里的巧克力糖
http.get("www.baidu.com").then((value) => null).catchError(onError);
Future<String> getFuture() {
return Future(() => "alice");
}
getFuture().then((value) => print(value));
Future<String> getFuture() {
return Future(() => "alice");
}
getFuture().then((value) => print(value));
print('hi');
void main() {
Future(() => print('event 1'));
Future.delayed(Duration(seconds: 1), () => print('event 2'));
scheduleMicrotask(() => print('microtask 1'));
Future.microtask(() => print('microtask 2'));
Future.value(123).then((value) => print("microtask 3"));
print("main1");
Future.sync(() => print('sync 1'));
Future.value(getName());
print('main 2');
Future.delayed(Duration(seconds: 1), () => print('delayed')).then((value) {
print('then');
scheduleMicrotask(() => print('micro'));
}).then((value) => print('then2'));
runApp(MyApp());
}
捕获异常
Future<String> getFuture() {
return Future.error(Exception("someting went wrong"));
}
getFuture()
.then((value) => print(value))
.catchError((err) => print(err))
.whenComplete(() => print('completed'));
Future<int> getFuture() async {
throw "oops";
}
void _incrementCounter() async {
try {
int d = await getFuture();
} catch (err) {
print(err);
}
setState(() {
_counter++;
});
}
Chain
Future<int> getFuture() {
return Future.value(100);
}
getFuture()
.then((value) {
print(value);
return value * 2;
})
.then((value) => print(value))
.catchError((err) => print(err))
.whenComplete(() => print('completed'));
async and await
Future<int> getFuture() async {
return 100;
}
void _incrementCounter() async {
int d = await getFuture();
print(d);
d = d * 2;
print(d);
setState(() {
_counter++;
});
}
深入了解FutureBuilder组件
Center(
child: FutureBuilder(
future: Future.delayed(Duration(seconds: 2), () => throw ('oops')),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Icon(Icons.error, size: 80);
}
if (snapshot.hasData) {
return Text("${snapshot.data}", style: TextStyle(fontSize: 72));
}
return CircularProgressIndicator();
},
),
),
Stream与StreamBuilder组件
定义stream
final future = Future.delayed(Duration(seconds: 1), () => 42);
final stream = Stream.periodic(Duration(seconds: 1), (_) => 42);
@override
void initState() {
future.then((value) => print("future conmpleted:$value"));
stream.listen((event) {
print("stream:$event");
});
super.initState();
}
StreamBuilder监听
final controller = StreamController();
@override
void dispose() {
controller.close();
super.dispose();
}
Center(
child: DefaultTextStyle(
style: Theme.of(context).textTheme.headline4,
child: Column(
children: [
RaisedButton(
child: Text('10'), onPressed: () => controller.sink.add(10)),
RaisedButton(
child: Text('1'), onPressed: () => controller.sink.add(1)),
RaisedButton(
child: Text('Hi'),
onPressed: () => controller.sink.add('hi')),
RaisedButton(
child: Text('Error'),
onPressed: () => controller.sink.addError('oops')),
RaisedButton(
child: Text('DONE'), onPressed: () => controller.sink.close()),
StreamBuilder(
stream: controller.stream,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('NONE:没有数据流');
break;
case ConnectionState.waiting:
return Text('WAITTING:等待数据流');
break;
case ConnectionState.active:
if (snapshot.hasError) {
return Text('ACTIVE:错误:${snapshot.error}');
} else {
return Text('ACTIVE:正常:${snapshot.data}');
}
break;
case ConnectionState.done:
return Text('DONE:数据流已经关闭');
break;
}
return Container();
},
),
],
),
),
),
StreamController.broadcast
final controller = StreamController.broadcast();
@override
void initState() {
super.initState();
controller.stream.listen((event) {
print("event:$event");
},
onError: (err) => print("ERROR:$err"),
onDone: () => print('DONE'));
}
async*
Stream<DateTime> getTime() async* {
while (true) {
await Future.delayed(Duration(seconds: 1));
yield DateTime.now();
}
}
getTime().listen((event) {
print('event:$event');
}, onDone: () => print('DONE'));
StreamBuilder(
stream: getTime(),
builder: (context, snapshot) {
...
....
实例:
import 'dart:async';
import 'dart:math';
import 'dart:ui';
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,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _inputController = StreamController.broadcast();
final _scoreController = StreamController.broadcast();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: StreamBuilder(
stream: _scoreController.stream.transform(TallyTransformer()),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text("Score:${snapshot.data}");
}
return Text('Score:0');
}),
),
body: Stack(
children: [
...List.generate(
5, (index) => Puzzle(_inputController.stream, _scoreController)),
Align(
alignment: Alignment.bottomCenter,
child: KeyPad(_inputController, _scoreController)),
],
),
);
}
}
class KeyPad extends StatelessWidget {
final _inputController;
final _scoreController;
KeyPad(this._inputController, this._scoreController);
@override
Widget build(BuildContext context) {
return GridView.count(
childAspectRatio: 3 / 1,
crossAxisCount: 3,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.all(0.0),
children: List.generate(9, (index) {
return FlatButton(
shape: RoundedRectangleBorder(),
color: Colors.primaries[index][200],
onPressed: () {
_inputController.add(index + 1);
_scoreController.add(-2);
},
child: Text(
'${index + 1}',
style: TextStyle(fontSize: 24),
));
}),
);
}
}
class TallyTransformer implements StreamTransformer {
int sum = 0;
StreamController _controller = StreamController();
@override
Stream bind(Stream stream) {
stream.listen((event) {
sum += event;
_controller.add(sum);
});
return _controller.stream;
}
@override
StreamTransformer<RS, RT> cast<RS, RT>() => StreamTransformer.castFrom(this);
}
class Puzzle extends StatefulWidget {
final inputStream;
final scoreStream;
Puzzle(this.inputStream, this.scoreStream);
@override
_PuzzleState createState() => _PuzzleState();
}
class _PuzzleState extends State<Puzzle> with SingleTickerProviderStateMixin {
int a, b, c;
Color color;
double x;
AnimationController _controller;
reset([from = 0.0]) {
c = Random().nextInt(9) + 1;
b = Random().nextInt(8);
a = c - b;
x = Random().nextDouble() * 300;
color = Colors.primaries[Random().nextInt(Colors.primaries.length)][200];
_controller.duration =
Duration(milliseconds: Random().nextInt(5000) + 5000);
_controller.forward(from: from);
}
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
reset(Random().nextDouble());
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
reset();
widget.scoreStream.add(-3);
}
});
widget.inputStream.listen((input) {
if (input == a + b) {
reset();
widget.scoreStream.add(5);
}
});
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Positioned(
left: x,
top: 600 * _controller.value - 100,
child: Container(
decoration: BoxDecoration(
color: color.withOpacity(0.5),
border: Border.all(color: Colors.black),
borderRadius: BorderRadius.circular(24)),
padding: EdgeInsets.all(8.0),
child: Text('$a+$b', style: TextStyle(fontSize: 24)),
),
);
},
);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】