Dart - 異步支持

Dart 代碼庫中有大量返回 FutureStream 對(duì)象的函數(shù)楞艾,這些函數(shù)都是 異步 的,它們會(huì)在耗時(shí)操作(比如I/O)執(zhí)行完畢前直接返回而不會(huì)等待耗時(shí)操作執(zhí)行完畢壳炎。

asyncawait 關(guān)鍵字用于實(shí)現(xiàn)異步編程拢操,并且讓你的代碼看起來就像是同步的一樣。

處理 Future

可以通過下面兩種方式抽诉,獲得 Future 執(zhí)行完成的結(jié)果:

  • 用 async 和 await。
  • 使用 Future API吐绵,具體描述迹淌,參考庫概覽

使用 asyncawait的代碼是異步的己单,但是看起來有點(diǎn)像同步代碼唉窃。例如,下面的代碼使用 await等待異步函數(shù)的執(zhí)行結(jié)果纹笼。

await lookUpVersion();

await 必須在帶有async關(guān)鍵字的 異步函數(shù) 中使用:

Future checkVersion() async {
  var version = await lookUpVersion();
  // 使用 version 繼續(xù)處理邏輯
}

備忘??:盡管異步函數(shù)可以處理耗時(shí)操作纹份,但是它并不會(huì)等待這些耗時(shí)操作完成,異步函數(shù)執(zhí)行時(shí)會(huì)在其遇到第一個(gè) await 表達(dá)式(詳情見)的時(shí)候返回一個(gè) Future 對(duì)象,然后等待 await表達(dá)式執(zhí)行完畢后繼續(xù)執(zhí)行蔓涧。

使用 try件已、catch以及finally來處理使用 await導(dǎo)致的異常:

try {
  version = await lookUpVersion();
} catch (e) {
  // 無法找到版本時(shí)做出的反應(yīng)
}

你可以在異步函數(shù)中多次使用 await關(guān)鍵字。例如元暴,下面代碼中等待了三次函數(shù)結(jié)果:

var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);

await表達(dá)式的返回值通常是一個(gè) Future對(duì)象篷扩;如果不是的話也會(huì)自動(dòng)將其包裹在一個(gè)Future對(duì)象里。Future 對(duì)象代表一個(gè)“承諾”茉盏,await表達(dá)式會(huì)阻塞直到需要的對(duì)象返回鉴未。

如果在使用 await 時(shí)導(dǎo)致編譯錯(cuò)誤,請(qǐng)確保 await 在一個(gè)異步函數(shù)中使用鸠姨。例如铜秆,如果想在 main() 函數(shù)中使用 await,那么 main() 函數(shù)就必須使用 async 關(guān)鍵字標(biāo)識(shí)讶迁。

Future main() async {
  checkVersion();
  print('在 Main 函數(shù)中執(zhí)行:版本是 ${await lookUpVersion()}');
}

聲明異步函數(shù)

定義 異步函數(shù) 只需在普通方法上加上 async關(guān)鍵字即可连茧。

將關(guān)鍵字async添加到函數(shù)并讓其返回一個(gè) Future 對(duì)象。假設(shè)有如下返回 String 對(duì)象的方法:

String lookUpVersion() => '1.0.0';

將其改為異步函數(shù)巍糯,返回值是 Future:

Future<String> lookUpVersion() async => '1.0.0';

注意梅屉,函數(shù)體不需要使用 Future API。如有必要鳞贷,Dart 會(huì)創(chuàng)建 Future 對(duì)象坯汤。

如果函數(shù)沒有返回有效值夭苗,需要設(shè)置其返回類型為 Future<void>爆安。

關(guān)于 futures、asyncawait 的使用介紹易遣,可以參見這個(gè) codelab: asynchronous programming codelab咱筛。

處理 Stream

如果想從 Stream 中獲取值搓幌,可以有兩種選擇:

  • 使用 async 關(guān)鍵字和一個(gè) 異步循環(huán)(使用 await for 關(guān)鍵字標(biāo)識(shí))。
  • 使用 Stream API迅箩。詳情參考庫概覽溉愁。

在使用 await for 關(guān)鍵字前,確保其可以令代碼邏輯更加清晰并且是真的需要等待所有的結(jié)果執(zhí)行完畢饲趋。例如拐揭,通常不應(yīng)該在 UI 事件監(jiān)聽器上使用 await for 關(guān)鍵字,因?yàn)?UI 框架發(fā)出的事件流是無窮盡的奕塑。

使用 await for 定義異步循環(huán)看起來是這樣的:

await for (varOrType identifier in expression) {
  // 每當(dāng) Stream 發(fā)出一個(gè)值時(shí)會(huì)執(zhí)行
}

表達(dá)式 的類型必須是 Stream堂污。執(zhí)行流程如下:

  • 1 等待直到 Stream 返回一個(gè)數(shù)據(jù)。

  • 2 使用 1 中 Stream 返回的數(shù)據(jù)執(zhí)行循環(huán)體龄砰。

  • 3 重復(fù) 1盟猖、2 過程直到 Stream 數(shù)據(jù)返回完畢讨衣。

使用 break 和 return 語句可以停止接收 Stream 數(shù)據(jù),這樣就跳出了循環(huán)并取消注冊(cè)監(jiān)聽 Stream式镐。

如果在實(shí)現(xiàn)異步 for 循環(huán)時(shí)遇到編譯時(shí)錯(cuò)誤反镇,請(qǐng)檢查確保 await for 處于異步函數(shù)中。 例如娘汞,要在應(yīng)用程序的 main() 函數(shù)中使用異步 for 循環(huán)歹茶,main() 函數(shù)體必須標(biāo)記為 async:

Future main() async {
  // ...
  await for (var request in requestServer) {
    handleRequest(request);
  }
  // ...
}

你可以查閱庫概覽中有關(guān) dart:async 的部分獲取更多有關(guān)異步編程的信息。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末价说,一起剝皮案震驚了整個(gè)濱河市辆亏,隨后出現(xiàn)的幾起案子风秤,更是在濱河造成了極大的恐慌鳖目,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缤弦,死亡現(xiàn)場(chǎng)離奇詭異领迈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)碍沐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門狸捅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人累提,你說我怎么就攤上這事尘喝。” “怎么了斋陪?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵朽褪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我无虚,道長(zhǎng)缔赠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任友题,我火速辦了婚禮嗤堰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘度宦。我一直安慰自己踢匣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布戈抄。 她就那樣靜靜地躺著符糊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪呛凶。 梳的紋絲不亂的頭發(fā)上男娄,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼模闲。 笑死建瘫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的尸折。 我是一名探鬼主播啰脚,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼实夹!你這毒婦竟也來了橄浓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤亮航,失蹤者是張志新(化名)和其女友劉穎荸实,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缴淋,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡准给,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了重抖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片露氮。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钟沛,靈堂內(nèi)的尸體忽然破棺而出畔规,到底是詐尸還是另有隱情,我是刑警寧澤恨统,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布叁扫,位于F島的核電站,受9級(jí)特大地震影響延欠,放射性物質(zhì)發(fā)生泄漏陌兑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一由捎、第九天 我趴在偏房一處隱蔽的房頂上張望兔综。 院中可真熱鬧,春花似錦狞玛、人聲如沸软驰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锭亏。三九已至,卻和暖如春硬鞍,著一層夾襖步出監(jiān)牢的瞬間慧瘤,已是汗流浹背戴已。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锅减,地道東北人糖儡。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像怔匣,于是被迫代替她去往敵國(guó)和親握联。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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

  • 二.莽原火 王昏庸每瞒,繼位三年金闽,大修行宮,納數(shù)美姬剿骨,奢糜無度 代芜,甚寵一妃,愛稱小憐懦砂。 小憐身段纖細(xì)妖嬈蜒犯,曲腔清悠婉轉(zhuǎn)...
    鶴逾白閱讀 702評(píng)論 0 0
  • 文 / 金小札 一個(gè)嚴(yán)肅羽资、不逗比的85后 01 今天和一個(gè)朋友去逛寵物市場(chǎng),回來的時(shí)候路過菜市場(chǎng)遵班,她下車順路買了幾...
    金小扎閱讀 566評(píng)論 0 1