isolate
Dart是基于單線程模型的語言。
但是我們?cè)陂_發(fā)中也會(huì)有請(qǐng)求網(wǎng)絡(luò)這樣的耗時(shí)操作赃泡,所以Dart也有并發(fā)機(jī)制寒波,稱為isolate。
Dart中的isolate無法共享內(nèi)存升熊。
Future
通常異步函數(shù)返回的對(duì)象就是一個(gè)Future
俄烁。
當(dāng)一個(gè)Future
執(zhí)行完后,可以使用then()
來處理返回的結(jié)果级野。
Future
對(duì)象其實(shí)就代表了在事件隊(duì)列中的一個(gè)事件的結(jié)果页屠。
基本使用
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將轉(zhuǎn)換為Future<int>返回,所以后續(xù)可以繼續(xù)使用then調(diào)用
},
).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
關(guān)鍵字蓖柔,將異步代碼寫成同步的形式辰企,可以有效得解決回調(diào)地獄的問題。
await
必須在async
方法內(nèi)使用渊抽。
該方法必須返回void
或Future
蟆豫;如果該方法返回值是一個(gè)Future
,則將自動(dòng)轉(zhuǎn)換懒闷。
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關(guān)鍵字十减,將異步代碼寫成同步的形式,可以有效得解決回調(diào)地獄的問題
// await必須在async方法內(nèi)使用
print(result.runtimeType);
print(result);
// 如果該方法返回值是一個(gè)Future愤估,則將自動(dòng)轉(zhuǎn)換
return result;
}
Stream
Stream
是一個(gè)異步數(shù)據(jù)源帮辟,是處理異步事件流的統(tǒng)一API。
單訂閱模式
// 通過Stream打開文件
Stream<List<int>> stream = File(r"D:\xxx\xxx\xxx.txt").openRead();
/// 默認(rèn)單訂閱模式
// 設(shè)置監(jiān)聽玩焰,返回一個(gè)訂閱者
var listen = stream.listen((event) {
print("listen");
});
// 調(diào)用cancel方法取消訂閱
listen.cancel();
// onData會(huì)替換掉之前設(shè)置的listen或onData方法
listen.onData((data) {
print("onData");
});
// onData會(huì)在訂閱者完成所有通知后執(zhí)行由驹,即可以做收尾工作
listen.onDone(() {
print("onDone");
});
// 暫停訂閱者
listen.pause();
// 恢復(fù)訂閱者
listen.resume();
// 單訂閱模式不支持添加兩個(gè)訂閱者,會(huì)拋異常
var listen2 = stream.listen((event) {
print("listen2");
});
單訂閱模式不支持添加兩個(gè)訂閱者,會(huì)拋異常
廣播模式(多訂閱)
// 通過Stream打開文件
Stream<List<int>> stream = File(r"D:\xxx\xxx\xxx.txt").openRead();
/// 廣播模式:多訂閱
/// 廣播可由單訂閱轉(zhuǎn)換而來
var broadcastStream = stream.asBroadcastStream();
broadcastStream.listen((event) {
print("broadcastStream 1");
});
broadcastStream.listen((event) {
print("broadcastStream 2");
});
broadcastStream.listen((event) {
print("broadcastStream 3");
});
/// 直接創(chuàng)建一個(gè)廣播
var controller = StreamController.broadcast();
// 發(fā)送一個(gè)消息
controller.add("1");
// 設(shè)置一個(gè)監(jiān)聽(設(shè)置監(jiān)聽前發(fā)送消息無法收到)
controller.stream.listen((event) {
print('接受廣播內(nèi)容:$event');
});
// 廣播用完記得close
controller.close();
由單訂閱轉(zhuǎn)換的廣播本質(zhì)還是單訂閱流蔓榄,所以添加訂閱者不會(huì)導(dǎo)致消息丟失并炮;
直接由StreamController
創(chuàng)建的廣播,后注冊(cè)的訂閱者無法收到之前發(fā)出的消息甥郑。