isolate
Dart是基于单线程模型的语言。
但是我们在开发中也会有请求网络这样的耗时操作,所以Dart也有并发机制,称为isolate。
Dart中的isolate无法共享内存。
Future
通常异步函数返回的对象就是一个Future
。
当一个Future
执行完后,可以使用then()
来处理返回的结果。
Future
对象其实就代表了在事件队列中的一个事件的结果。
基本使用
File(r"D:\xxx\xxx\xxx.txt")
// File().readAsString()返回Future<String>
.readAsString()
// 可使用then来接收Future<String>返回的值
.then((value) => print(value))
// 可使用catchError来捕获异常信息
.catchError((s) => print(s));
串行组合
File(r"D:\xxx\xxx\xxx.txt").readAsString().then(
(value) {
print(value);
return 1; //return将转换为Future<int>返回,所以后续可以继续使用then调用
},
).then((value) => print(value));
并行组合
Future f1 = Future.delayed(Duration(seconds: 3), () {
return 1;
});
Future f2 = Future.delayed(Duration(seconds: 5), () {
return 3;
});
Future.wait([f1, f2]).then((value) {
print(value[0]); // 返回f1的值
print(value[1]); // 返回f2的值
});
async & await
可以使用async
和await
关键字,将异步代码写成同步的形式,可以有效得解决回调地狱的问题。
await
必须在async
方法内使用。
该方法必须返回void
或Future
;如果该方法返回值是一个Future
,则将自动转换。
void main() async {
var result = await readTxt();
print(result);
}
Future<String> readTxt() async {
var result = await File(r"D:\xxx\xxx\xxx.txt").readAsString();
// 可以使用async和await关键字,将异步代码写成同步的形式,可以有效得解决回调地狱的问题
// await必须在async方法内使用
print(result.runtimeType);
print(result);
// 如果该方法返回值是一个Future,则将自动转换
return result;
}
Stream
Stream
是一个异步数据源,是处理异步事件流的统一API。
单订阅模式
// 通过Stream打开文件
Stream<List<int>> stream = File(r"D:\xxx\xxx\xxx.txt").openRead();
/// 默认单订阅模式
// 设置监听,返回一个订阅者
var listen = stream.listen((event) {
print("listen");
});
// 调用cancel方法取消订阅
listen.cancel();
// onData会替换掉之前设置的listen或onData方法
listen.onData((data) {
print("onData");
});
// onData会在订阅者完成所有通知后执行,即可以做收尾工作
listen.onDone(() {
print("onDone");
});
// 暂停订阅者
listen.pause();
// 恢复订阅者
listen.resume();
// 单订阅模式不支持添加两个订阅者,会抛异常
var listen2 = stream.listen((event) {
print("listen2");
});
单订阅模式不支持添加两个订阅者,会抛异常
广播模式(多订阅)
// 通过Stream打开文件
Stream<List<int>> stream = File(r"D:\xxx\xxx\xxx.txt").openRead();
/// 广播模式:多订阅
/// 广播可由单订阅转换而来
var broadcastStream = stream.asBroadcastStream();
broadcastStream.listen((event) {
print("broadcastStream 1");
});
broadcastStream.listen((event) {
print("broadcastStream 2");
});
broadcastStream.listen((event) {
print("broadcastStream 3");
});
/// 直接创建一个广播
var controller = StreamController.broadcast();
// 发送一个消息
controller.add("1");
// 设置一个监听(设置监听前发送消息无法收到)
controller.stream.listen((event) {
print('接受广播内容:$event');
});
// 广播用完记得close
controller.close();
由单订阅转换的广播本质还是单订阅流,所以添加订阅者不会导致消息丢失;
直接由StreamController
创建的广播,后注册的订阅者无法收到之前发出的消息。
网友评论