dart 語言的非同步 同步 構造器 隔離 元註解 註釋方式
1. async await
下面依次呼叫 三個方法 輸出的順序為1--3--4--2--5
await該關鍵字會執行暫停當前執行緒 等外部執行完畢再執行剩下的
main() async {
// async wait
getName1();
getName2();
getName3();
}
複製程式碼
/ async wait
Future<void> getName1() async {
// getStr1();//可以不用await打斷點看下await後的區別
await getStr1(); //遇到第一個await表示式執行暫停,返回future物件,await表示式執行完成後繼續執行
await getStr2(); //await表示式可以使用多次
print('5');
}
getStr1() {
print('1');
}
getStr2() {
print('2');
}
getName2() {
print('3');
}
getName3() {
print('4');
}
複製程式碼
2. 佇列新增
- Future
每次新建一個Future 會將這個Future新增到佇列當中 先新增先執行 下面程式碼的輸入順序為f7--f1--f6--f3--f5--ff2--f4
void testFuture() {
Future f = new Future(() => print("f1"));
Future f1 = new Future(() => null); //7163524
// Future f1 = new Future.delayed(Duration(seconds: 1) ,() => null);//7132465
Future f2 = new Future(() => null);
Future f3 = new Future(() => null);
f3.then((_) => print("f2"));
f2.then((_) {
print("f3");
new Future(() => print("f4"));
f1.then((_) {
print("f5");
});
});
f1.then((m) {
print("f6");
});
print("f7");
}
複製程式碼
- scheduleMicrotask 微佇列
微佇列會優先與佇列執行,微佇列執行會在當前正在執行的Future任務 執行完才會去執行微佇列的任務, 如果then返回一個future任務那這個任務也會放到佇列中, delayed延遲佇列會在最後執行 下面的程式碼輸出順序為s9--s1--s8--s3--s4--s6--s5--s10--s7--s11--s12--s2
void testScheduleMicrotask() {
//918346572
scheduleMicrotask(() => print('s1'));
new Future.delayed(new Duration(seconds: 1), () => print('s2'));
new Future(() => print('s3')).then((_) {
print('s4');
scheduleMicrotask(() => print('s5'));
}).then((_) => print('s6'));
new Future(() => print('s10'))
.then((_) => new Future(() => print('s11')))
.then((_) => print('s12'));
new Future(() => print('s7'));
scheduleMicrotask(() => print('s8'));
print('s9');
}
複製程式碼
3. isolates 隔離
所有的 Dart 程式碼在 isolates 中執行而不是執行緒。 每個 isolate 都有自己的堆記憶體,並且確保每個 isolate 的狀態都不能被其他 isolate 訪問。 其實 一個main方法就是一個隔離
main() async {
var receivePort = new ReceivePort();
await Isolate.spawn(echoo, receivePort.sendPort);
receivePort.listen((s) {
if (s is SendPort) {
s.send("不我想要桃子");
} else
print(s);
});
}
/// 新isolate的入口函式
echoo(SendPort sendPort) async {
// 例項化一個ReceivePort 開啟接收埠以接收訊息
var port = new ReceivePort();
// 把它的sendPort傳送給宿主isolate,以便宿主可以給它傳送訊息
sendPort.send(port.sendPort);
sendPort.send("給你爛蘋果");
// 監聽迴圈接收訊息
port.listen((s) {
print(s);
});
}
複製程式碼
4. 生成器
sync* async用於生成 Iterrable 和 Stream yield yield 優化效能
- 同步生成器
返回值是Iterable 需要呼叫 moveNext() 才會執行迭代
//呼叫getSyncGenerator立即返回Iterable
var it = getSyncGenerator(5).iterator;
// 呼叫moveNext方法時getSyncGenerator才開始執行
while (it.moveNext()) {
print(it.current);
}
//同步生成器: 使用sync*,返回的是Iterable物件
Iterable<int> getSyncGenerator(int n) sync* {
print('start');
int k = n;
while (k > 0) {
//yield會返回moveNext為true,並等待 moveNext 指令
yield k--;
}
print('end');
}
複製程式碼
- 非同步生成器
返回值是Stream 執行了只有執行了listen之後函式才會執行,也可以使用可以使用StreamSubscription物件對資料流進行控制
//呼叫getAsyncGenerator立即返回Stream,只有執行了listen,函式才會開始執行
// getAsyncGenerator(5).listen((value) => print(value));
StreamSubscription subscription = getAsyncGenerator(5).listen(null);
subscription.onData((value) {
print(value);
if (value >= 2) {
subscription.pause(); //可以使用StreamSubscription物件對資料流進行控制
}
});
//非同步生成器: 使用async*,返回的是Stream物件
Stream<int> getAsyncGenerator(int n) async* {
print('start');
int k = 0;
while (k < n) {
//yield不用暫停,資料以流的方式一次性推送,通過StreamSubscription進行控制
yield k++;
}
print('end');
}
複製程式碼
- 遞迴生成器
//同步
var it1 = getSyncRecursiveGenerator(5).iterator;
while (it1.moveNext()) {
print(it1.current);
}
//非同步
getAsyncRecursiveGenerator(5).listen((value) => print(value));
//遞迴生成器:使用yield*
Iterable<int> getSyncRecursiveGenerator(int n) sync* {
if (n > 0) {
yield n;
yield* getSyncRecursiveGenerator(n - 1);
}
}
//非同步遞迴生成器
Stream<int> getAsyncRecursiveGenerator(int n) async* {
if (n > 0) {
yield n;
yield* getAsyncRecursiveGenerator(n - 1);
}
}
複製程式碼
5. 元註解
- @deprecated 過時
- @override 重寫
- 自定義註解
class Todo {
final String who;
final String what;
const Todo({this.who, this.what});
}
複製程式碼
6. 註釋方式
- 這是單行註釋
// 這是單行註釋
複製程式碼
- 多行註釋
/*
* 這是多行註釋
* 這是多行註釋
*/
複製程式碼
- 文件註釋
兩種方式
/// 這是文件註釋
/**
* 這是文件註釋
*/
複製程式碼