Flutter 學習(三) dart基礎

Jacksonl發表於2019-10-30

dart 語言的非同步 同步 構造器 隔離 元註解 註釋方式

1. async await

下面依次呼叫 三個方法 輸出的順序為1--3--4--2--5await該關鍵字會執行暫停當前執行緒 等外部執行完畢再執行剩下的

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. 註釋方式

  • 這是單行註釋
// 這是單行註釋
複製程式碼
  • 多行註釋
/*
 * 這是多行註釋
 * 這是多行註釋 
 */

複製程式碼
  • 文件註釋

兩種方式
/// 這是文件註釋

/**
  * 這是文件註釋
  */

複製程式碼

相關文章