<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    【Flutter】Future, async, await

    共 6352字,需瀏覽 13分鐘

     ·

    2021-06-09 22:00


    Dart 為單線程語言,但它提供了異步編程的方式,Future, async, await 為異步編程的類和關(guān)鍵字,

    Future

    Future.then

    異步編程最常用的場景是訪問網(wǎng)絡(luò)接口,返回數(shù)據(jù),這里我們模擬這樣的場景,2秒后返回網(wǎng)絡(luò)數(shù)據(jù),代碼如下:

    Future<String> getMyName() {
      Future.delayed(Duration(seconds: 2), () => '老孟');
    }

    下面將獲取到的數(shù)據(jù)打印出來,

    void _incrementCounter() {
      var name = getMyName();
      print('name:$name');
    }

    上面的用法是典型的錯誤用法,而且也是大部分初學(xué)者容易犯錯的地方,getMyName 為 Future 方法,表示此方法為異步方法。

    上面的代碼打印日志如下:

    flutter: name:Instance of 'Future<String>'

    正確的用法如下:

    void _incrementCounter() {
      getMyName().then((String value) {
        print('name:$value');
      });
    }

    2秒后打印日志:

    flutter: name:老孟

    Future.then.catchError

    有這樣一個Future方法:延遲1秒將字符串轉(zhuǎn)換為int類型,代碼如下:

    Future<int> parse(String value) {
      return Future.delayed(Duration(seconds: 1), () {
        return int.parse(value);
      });
    }

    調(diào)用此方法:

    parse("2").then((int value) {
      print('value:$value');
    });

    此時可以正確轉(zhuǎn)換,輸出日志:

    flutter: value:2

    如果入?yún)榉菙?shù)字,則會出現(xiàn)轉(zhuǎn)換異常,代碼如下:

    parse("2a").then((int value) {
      print('value:$value');
    });

    運(yùn)行,拋出異常:

    此時,需要捕獲異常并做處理,代碼如下:

    parse("2a").then((int value) {
      print('value:$value');
    }).catchError((error){
      print('error:$error');
    });

    輸出日志:

    flutter: error:FormatException: Invalid radix-10 number (at character 1)
    2a
    ^

    Future 的異常不能使用 try..catch 捕獲。

    Future 可以返回任意類型的值,也可以不返回值,

    Future<void> futureVoid() {
      return Future.delayed(Duration(seconds: 1), () {
        //do something
      });
    }

    Future.delayed

    延遲處理,上面已經(jīng)多次使用,延遲1秒執(zhí)行:

    Future.delayed(Duration(seconds: 1), () {
      //do something
    });

    Future.value

    創(chuàng)建一個帶返回值的 Future

    Future<String> futureValue() {
      return Future.value('老孟');
    }

    Future.any

    返回[futures]中要完成的第一個Future的結(jié)果,返回的第一個結(jié)果表示已完成,其他Future結(jié)果被拋棄。如果[futures]為空,或者沒有一個Future完成,那么Future永遠(yuǎn)不會完成。

    Future<String> futureAny() {
      return Future.any([
        Future.delayed(Duration(seconds: 1),()=> '1'),
        Future.delayed(Duration(seconds: 2),()=> '2'),
        Future.delayed(Duration(seconds: 3),()=> '3'),
      ]);
    }

    輸出日志:

    flutter: value:1

    Future.microtask

    Flutter 的 main isolate 中有2個隊列:Event Queue 和 Microtask Queue ,這兩個 Queue 區(qū)別是 Microtask Queue執(zhí)行的優(yōu)先級比Event Queue高。

    Future.microtask 是向Microtask Queue添加任務(wù),而其他Future 方法是向Event Queue中添加任務(wù)。

    Future<String> futureMicrotask() {
      return Future.microtask(()=>'老孟');
    }

    Future.sync

    表示Future中代碼是同步執(zhí)行的。

    Future<void> futureSync() {
      return Future.sync(()=>print('Future.sync'));
    }

    調(diào)用:

    void _incrementCounter() {
      print('Future.sync begin');
      futureSync();
      print('Future.sync end');
    }

    打印日志:

    flutter: Future.sync begin
    flutter: Future.sync
    flutter: Future.sync end

    Future.error

    返回異常,可以通過catchError捕獲。

    Future<void> futureSync() {
      return Future.sync(() => print('Future.sync'));
    }

    調(diào)用:

    futureError().catchError((error) {
      print('$error');
    });

    輸出日志:

    flutter: this is error

    Future.doWhile

    重復(fù)執(zhí)行操作,直到返回 false。

    Future<void> futureDoWhile() {
      var i = 0;
      return Future.doWhile(() {
        print('i:$i');
        return Future.value(i++ < 10);
      });
    }

    日志輸出:

    flutter: i:0
    flutter: i:1
    flutter: i:2
    flutter: i:3
    flutter: i:4
    flutter: i:5
    flutter: i:6
    flutter: i:7
    flutter: i:8
    flutter: i:9
    flutter: i:10

    Future.forEach

    遍歷完所有的值或者拋出異常才變?yōu)橥瓿蔂顟B(tài)。

    Future<void> futureForEach() {
      return Future.forEach([1,2,3,5],(value){
        print('value:$value');
      });
    }

    日志輸出:

    flutter: value:1
    flutter: value:2
    flutter: value:3
    flutter: value:5

    async, await

    async 和 await 關(guān)鍵字允許我們像寫同步代碼一樣寫異步代碼,有如下異步函數(shù):

    Future<int> parse(String value) {
      return Future.delayed(Duration(seconds: 1), () {
        return int.parse(value);
      });
    }

    可以使用如下方法獲取結(jié)果:

    void _incrementCounter() {
      parse('2').then((value) => print('value:$value'));
    }

    也可以使用如下方法:

    void _incrementCounter() async {
      var result = await parse('2');
      print('result:$result');
    }

    日志輸出:

    flutter: result:2

    使用async 和 await 可讀性更強(qiáng)。

    使用 async 修飾的方法返回 Future,是異步方法。

    Future<int> toInt(String value) async {
      return int.parse(value);
    }

    async 和 await 的異常捕獲需要使用try..catcch

    void _incrementCounter() async {
      try{
        await parse('1');
      }catch(e){
        
      }
    }

    總結(jié)

    • async 和 await 關(guān)鍵字可以認(rèn)為是 Future 的語法糖。

    • async 和 await 關(guān)鍵字可以有效的解決 Future.then 嵌套問題

      void _incrementCounter() {
        fun1().then((value) {
          fun2().then((value) {
            fun3().then((value) {});
          });
        });
      }

      Future<String> fun1() {
        return Future.value('a');
      }

      Future<String> fun2() {
        return Future.value('b');
      }

      Future<String> fun3() {
        return Future.value('c');
      }

      這種地獄嵌套可讀性非常差,使用async 和 await 寫法:

      void _incrementCounter() async {
        var result1 = await fun1();
        var result2 = await fun2();
        var result3 = await fun3();
      }
    • Future.then 可以使用鏈?zhǔn)秸{(diào)用

      void _incrementCounter() async {
        fun1()
            .then((value) {})
            .then((value){});
      }


    你可能還喜歡

    關(guān)注「老孟Flutter」
    讓你每天進(jìn)步一點點


    瀏覽 163
    點贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報
    評論
    圖片
    表情
    推薦
    點贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    免费在线观看黄色视频网站 | 91AV影院 | 蜜臀精品久久久999久久久酒店 | 性猛交XXXXX富婆免费视频 | 舔逼乳头大片 |