「这是我参与11月更文应战的第8天,活动详情检查:2021最终一次更文应战」
Future异步
在上面网络恳求的时分用到了Future
,那么这个究竟是什么?Fluture
是主线程傍边的异步代码
- 下面打印的次序是什么:
void main() {
testFuture();
print('A');
}
void testFuture() async {
Future(() {
print('C');
});
print('B');
}
- 参加
await
之后打印的次序是什么?
void main() {
testFuture();
print('A');
}
void testFuture() async {
await Future(() {
print('C');
}).then((value) => print('D'));
print('B');
}
通过测验发现运用
Future
润饰的代码块会异步履行,不会卡住当时的线程。如果希望在这个异步使命履行完结之后再操作,需求在Future前面加上一个await。
- 多个
Future
并行的时分的打印次序:
void main() {
testFuture();
print('A');
}
void testFuture() async {
Future(() {
return '使命1';
}).then((value) => print('$value 履行完毕'));
Future(() {
return '使命2';
}).then((value) => print('$value 履行完毕'));
Future(() {
return '使命3';
}).then((value) => print('$value 履行完毕'));
Future(() {
return '使命4';
}).then((value) => print('$value 履行完毕'));
print('使命增加完毕');
}
调整次序或者是让其间的一个使命参加睡觉等多项测验之后,发现多个
Future
并行发现这个履行的次序便是增加的次序。
- 有依赖关系的
Future
打印次序:
void testFuture() async {
Future(() {
return '使命1';
}).then((value) {
print('$value完毕');
return '$value使命2';
}).then((value) {
print('$value完毕');
return '$value使命3';
}).then((value) {
print('$value完毕');
return '$value使命4';
});
}
- 多个
Future
履行完结之后再操作:
void testFuture() async {
Future.wait([
Future(() {
return '使命1';
}),
Future(() {
return '使命2';
}),
Future(() {
return '使命3';
}),
Future(() {
return '使命4';
}),
]).then((value) => print('$value')); // wait里边的履行次序也是增加的次序
}
-
scheduleMicrotask
能够插队到Future
使命前面
void testFuture() async {
Future.wait([
Future(() {
return '使命1';
}),
Future(() {
return '使命2';
}),
Future(() {
return '使命3';
}),
Future(() {
return '使命4';
}),
]).then((value) => print('$value'));
scheduleMicrotask(() {
print('scheduleMicrotask');
});
}
Dart
中就只有两种行列:一种是事件行列,一种是微使命行列,微使命行列的优先级一直高于事件行列。 下图为官方图:
- 下列打印的次序是什么?
void testFuture() async {
Future x = Future(() => print('A'));
Future(() => print('B'));
scheduleMicrotask(() {
print('C');
});
x.then((value) => print('D'));
print('E');
}
首要肯定是主线程的E
,然后是微使命的C
,剩余的两个Future
依照增加的次序履行,首要履行A和D最终是B
-
Fluture
中嵌套微使命的履行次序:
void testFuture() async {
Future(() => print('A')).then((value) {
scheduleMicrotask(() {
print('D');
});
}).then((value) => print('F'));
Future(() => print('B'));
scheduleMicrotask(() {
print('C');
});
print('E');
}
这儿能够这么了解:then
后边的代码能够了解为丢到了微使命行列去履行。
补充:运用Flutter的时分尽量运用链式调用,保证在最终调用.catchError
来捕获异常
getData() async {
print('开始了');
await Future(() {
for (int i = 0; i < 100; i++) {}
return '循环完毕';
})
.then((value) => print('$value'))
.whenComplete(() => print('完结了'))
.catchError((e) => print(e.toString()));
print('await之后的代码');
}
Dart中的多线程
Dart傍边的Isolate
更像一个进程,有独立的内存空间。意味着每个进程之间的数据是独立的,不存在争夺空间的情况,所以不需求锁的概念。
void main() {
IsolateDemo();
}
void IsolateDemo() {
print('1');
Isolate.spawn(func, 3);
Isolate.spawn(func, 4);
Isolate.spawn(func, 5);
Isolate.spawn(func, 6);
Isolate.spawn(func, 7);
Isolate.spawn(func, 8);
Isolate.spawn(func, 9);
sleep(Duration(seconds: 3));
print('2');
}
上面说了不存在同一块内存的问题,咱们也来验证一下,在下面的代码中,我在Isolate
中修改了a的值,那么最终打印的a=?
int a = 100;
void IsolateDemo() {
print('1');
Isolate.spawn(func, 3);
Isolate.spawn(func, 4);
Isolate.spawn(func, 5);
Isolate.spawn(func, 6);
Isolate.spawn(func, 7);
Isolate.spawn(func, 8);
Isolate.spawn(func, 9);
sleep(Duration(seconds: 3));
print('2');
print('a = $a');
}
func(int count) {
print('$count');
a = count;
}
经验证,最终a还是等于100.也便是说在Isolate
中的修改并没有效果。
ReceivePort & Isolate
void IsolateDemo() {
print('1');
ReceivePort port = ReceivePort();
Isolate.spawn(func, port.sendPort);
port.listen((message) {
print('message=$message');
});
sleep(Duration(seconds: 3));
print('2');
}
func(SendPort port) {
port.send(10);
}
上面的代码还是有一点需求完善的当地:此时注意需求手动的封闭端口和销毁Isolate
void IsolateDemo() async {
print('1');
ReceivePort port = ReceivePort();
Isolate iso = await Isolate.spawn(func, port.sendPort);
port.listen((message) {
print('message=$message');
port.close();
iso.kill();
});
sleep(Duration(seconds: 3));
print('2');
}
compute
用法跟Isolat
e差不多,是在Isolate
上的进一步包装。compute
不需求手动kill
void main() {
Comouterdemo();
}
void Comouterdemo() {
print('1');
compute(func1, 10);
sleep(Duration(seconds: 3));
print('2');
}
func1(int num) {
print('$num');
}
调配await
异步运用
void main() {
Comouterdemo();
}
void Comouterdemo() async {
print('1');
int result = await compute(func1, 10);
sleep(Duration(seconds: 3));
print('result=$result');
print('2');
}
int func1(int num) {
print('$num');
return num;
}
一些小知识
- 关于import, as关键字便是给库起别名,意图是避免类名、方法名抵触
import 'package:http/http.dart' as http;
- 导入库,默许是整个文件都会导入,如果需求指定的话有两个关键字。
show
:履行需求导入的内容;hide:
需求隐藏的内容 -
pubspec.yaml
中publish_to
:指定发布到哪里去,默许的都是到pub.dev
里边去 -
pubspec.yaml
中version
: 当时项意图版别号 -
pubspec.yaml
中 Dart的版别environment:sdk: ">=2.12.0 <3.0.0"
-
pubspec.yaml
中dev_dependencies
: 开发环境依赖的版别打包的时分不会有这些 -
pubspec.yaml
中dependencies
: 第三方库导入位置。dio:^4.0.1
大版别不变的区间写法,相当于>=4.0.1 <5.0.0
;dio:4.0.1
指定4.0.1版别;dio:any
恣意版别