Flutter異步操作的通行證——Future的使用

前言

最近flutter可謂是炙手可熱啊,極大多數(shù)的移動(dòng)開(kāi)發(fā)者以及前端開(kāi)發(fā)人員都會(huì)利用空閑時(shí)間選擇去學(xué)習(xí)一下這個(gè)由Google一手打造的跨平臺(tái)的移動(dòng)UI框架。而本文要講的是關(guān)于在flutter中進(jìn)行異步操作的相關(guān)知識(shí)。

關(guān)于Future

1.眾所周知,flutter采用的是Dart語(yǔ)言。在我們?nèi)粘5囊苿?dòng)開(kāi)發(fā)中,總會(huì)遇到一些需要延時(shí)操作的場(chǎng)景,例如網(wǎng)絡(luò)請(qǐng)求,例如等待某個(gè)操作完成后再操作另一個(gè)事件。在Android中我們可以開(kāi)啟一個(gè)新的線程來(lái)進(jìn)行相關(guān)的操作,而現(xiàn)在Dart是一個(gè)單線程的語(yǔ)言。因此,這時(shí)我們不得不采取異步的方式來(lái)進(jìn)行類似的延時(shí)操作。
2.說(shuō)到flutter中的異步操作,就不得不說(shuō)到Future這個(gè)類。它的字面意思就是未來(lái)的意思,而在flutter中,它即表示在未來(lái)某一時(shí)間獲取想要的對(duì)象的一種方式。

場(chǎng)景描述

1.首先,我們舉個(gè)帶有耗時(shí)操作的場(chǎng)景實(shí)例。用龜兔賽跑舉例子,將事件分了四個(gè)步驟。

// 兔子和烏龜同時(shí)開(kāi)始起跑
  String startRun() {
    print("兔子和烏龜同時(shí)開(kāi)始起跑!");
    return "兔子和烏龜同時(shí)開(kāi)始起跑";
  }
  // 兔子等待烏龜并開(kāi)始睡覺(jué)(此方法為耗時(shí)操作)
  String tuziWaitWugui() {
    print("兔子醒來(lái)后發(fā)現(xiàn)烏龜已經(jīng)到終點(diǎn)了");
    return "兔子醒來(lái)后發(fā)現(xiàn)烏龜已經(jīng)到終點(diǎn)了";
  }
  // 烏龜超越兔子
  String wuguiOverstepTuzi() {
    print("烏龜趁著兔子睡覺(jué)而超越了兔子!");
    return "烏龜趁著兔子睡覺(jué)而超越了兔子";
  }
  // 烏龜贏了比賽
  String wuguiWinGame() {
    print("烏龜率先到達(dá)了終點(diǎn)!");
    return "烏龜率先到達(dá)了終點(diǎn)";
  }

2.如上代碼所示,第二個(gè)兔子等待烏龜?shù)姆椒ㄊ且粋€(gè)耗時(shí)方法,因?yàn)樗X(jué)是一個(gè)過(guò)程。下面我們?cè)趂lutter中按順序執(zhí)行這四個(gè)方法。

void main() { // 此方法會(huì)在一個(gè)StatefulWidget組件的initState方法中調(diào)用(這里的基礎(chǔ)知識(shí)還請(qǐng)自行科普)
    startRun();
    tuziWaitWugui();
    wuguiOverstepTuzi();
    wuguiWinGame();
  }

3.在控制臺(tái)我們會(huì)發(fā)現(xiàn)輸入的print信息如下:

兔子和烏龜同時(shí)開(kāi)始起跑!
兔子醒來(lái)后發(fā)現(xiàn)烏龜已經(jīng)到終點(diǎn)了!
烏龜趁著兔子睡覺(jué)而超越了兔子!
烏龜率先到達(dá)了終點(diǎn)!

我們會(huì)發(fā)現(xiàn),由于Dart是單線程語(yǔ)言,因此只有當(dāng)方法二執(zhí)行完才能執(zhí)行后面的方法。也就是說(shuō)只要兔子不醒,烏龜是無(wú)法超過(guò)兔子的,這顯然不符合事件的邏輯。這時(shí),我們來(lái)看一下Future的使用,它就是專門用來(lái)解決這種需要異步操作的問(wèn)題的。

Future使用

1.Future是基于觀察者模式的,它定義了未來(lái)將要發(fā)生的事情。它有兩種使用方式,首先我們通過(guò)它的構(gòu)造函數(shù)來(lái)創(chuàng)建它。

void main() {
    Future<String> tuziWaitFuture = new Future(tuziWaitWugui); // 創(chuàng)建Future,并將耗時(shí)方法二傳給構(gòu)造函數(shù)
    // 執(zhí)行事件
    startRun();
    tuziWaitFuture.then((str) { // 異步操作邏輯在這里
      print(str);
    }).whenComplete(() { // 異步完成時(shí)的回調(diào)
      print("whenComplete");
    }).catchError((error) { // 捕獲異常或者異步出錯(cuò)時(shí)的回調(diào)
      print("catchError");
    });
    wuguiOverstepTuzi();
    wuguiWinGame();
  }

// 控制臺(tái)輸出信息如下:
兔子和烏龜同時(shí)開(kāi)始起跑!
烏龜趁著兔子睡覺(jué)而超越了兔子!
烏龜率先到達(dá)了終點(diǎn)!
兔子醒來(lái)后發(fā)現(xiàn)烏龜已經(jīng)到終點(diǎn)了!
whenComplete

現(xiàn)在看輸入結(jié)果完全符合事件邏輯了吧!這里我們通過(guò)使用構(gòu)造方法來(lái)new一個(gè)Future。在Future的構(gòu)造方法中我們可以直接傳入一個(gè)方法,并且方法的返回值類型需要和Future的泛型一致。然后,我們使用了Future的三個(gè)回調(diào)方法,其中then方法中的參數(shù)就是傳入的方法中的返回值。同時(shí)需要說(shuō)明的是,我們的異步操作的邏輯就可以寫在then回調(diào)中。其余兩個(gè)回調(diào)方法我在代碼中的注釋也寫的很清楚了。

2.通過(guò)構(gòu)造函數(shù)創(chuàng)建Future的方式已經(jīng)知道。現(xiàn)在我們聯(lián)想這樣一個(gè)場(chǎng)景,譬如網(wǎng)絡(luò)請(qǐng)求,我們需要等待一個(gè)方法執(zhí)行完返回我們所需的數(shù)據(jù)后才能繼續(xù)向下執(zhí)行。這時(shí),我們就需要用到async和await關(guān)鍵字了。

// 首先聲明一個(gè)方法,返回Future對(duì)象,模擬網(wǎng)絡(luò)請(qǐng)求延時(shí)了一秒
Future<String> getNewsData() {
    return new Future.delayed(new Duration(milliseconds: 1000), () {
      return "新聞數(shù)據(jù)已經(jīng)返回";
    });
  }
// 在之前的main()方法中調(diào)用該方法
void main() async {
    String newsData = await getNewsData();
    print(newsData);
    print("數(shù)據(jù)回來(lái)之后我才打印");
  }
// 執(zhí)行后,控制臺(tái)輸出信息
新聞數(shù)據(jù)已經(jīng)返回
數(shù)據(jù)回來(lái)之后我才打印

首先,我們用Future.delayed方式創(chuàng)建一個(gè)延時(shí)返回一個(gè)字符串的方法,該方法返回的是一個(gè)Future對(duì)象。然后,我們?cè)趍ain方法中調(diào)用此函數(shù),并且將返回值賦給newsData變量。此時(shí)如果我們直接用等號(hào)將變量和方法連接IDE會(huì)提示報(bào)錯(cuò),錯(cuò)誤提示為方法返回的是一個(gè)Future對(duì)象。這時(shí)我們就要在方法的調(diào)用前面加上一個(gè)await關(guān)鍵字,同時(shí)還要在main方法的后面添加async關(guān)鍵字。
至于為什么這樣,我只能說(shuō)說(shuō)我的個(gè)人理解。因?yàn)镕uture表示未來(lái)想要的某個(gè)對(duì)象,所以我們需要有一個(gè)東西來(lái)聲明需要等待這個(gè)未來(lái)的對(duì)象,因此便出現(xiàn)了await關(guān)鍵字來(lái)標(biāo)明要等待這個(gè)對(duì)象返回。而至于async關(guān)鍵字,因?yàn)間etNewsData是執(zhí)行一個(gè)異步操作,所以要在方法上標(biāo)明這個(gè)方法中會(huì)調(diào)用異步操作方法。同時(shí),要記住一點(diǎn)就是await必須放在有async 標(biāo)識(shí)的函數(shù)里,才能執(zhí)行。

結(jié)語(yǔ)

本人也是剛剛?cè)腴Tflutter的小菜鳥(niǎo),之前對(duì)flutter包括Dart語(yǔ)言都是一無(wú)所知的。所以,也是根據(jù)自己的理解并參考了一些文章來(lái)總結(jié)了關(guān)于Future的簡(jiǎn)單使用方式,如有不對(duì)的地方還望指出哈!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,179評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 175,628評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 62,642評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,444評(píng)論 6 405
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 54,948評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,185評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,717評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,794評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 34,418評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 35,671評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,414評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,750評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容