庫(kù)
? ??import?和?library?關(guān)鍵字可以幫助你創(chuàng)建一個(gè)模塊化和可共享的代碼庫(kù)准夷。代碼庫(kù)不僅只是提供 API 而且還起到了封裝的作用:以下劃線(_)開(kāi)頭的成員僅在代碼庫(kù)中可見(jiàn)诡延。?
? ??每個(gè) Dart 程序都是一個(gè)庫(kù),即便沒(méi)有使用關(guān)鍵字?library?指定歉摧。
? ? 使用庫(kù)
? ??????使用?import?來(lái)指定命名空間以便其它庫(kù)可以訪問(wèn)。
? ? ? ? 例如?import 'dart:html';
? ??????import?的唯一參數(shù)是用于指定代碼庫(kù)的 URI礼饱,對(duì)于 Dart 內(nèi)置的庫(kù)作郭,使用?dart:xxxxxx?的形式。而對(duì)于其它的庫(kù)逗抑,你可以使用一個(gè)文件系統(tǒng)路徑或者以?package:xxxxxx?的形式剧辐。?package:xxxxxx?指定的庫(kù)通過(guò)包管理器(比如 pub 工具)來(lái)提供:
? ??????import 'package:test/test.dart';
? ??指定庫(kù)前綴
? ??????如果你導(dǎo)入的兩個(gè)代碼庫(kù)有沖突的標(biāo)識(shí)符,你可以為其中一個(gè)指定前綴锋八。比如如果 library1 和 library2 都有 Element 類浙于,那么可以這么處理:
? ??導(dǎo)入庫(kù)的一部分
? ??????如果你只想使用代碼庫(kù)中的一部分,你可以有選擇地導(dǎo)入代碼庫(kù):
? ? 延遲加載庫(kù)
? ??????延遲加載(也常稱為?懶加載)允許應(yīng)用在需要時(shí)再去加載代碼庫(kù)挟纱,下面是可能使用到延遲加載的場(chǎng)景:
? ? ? ? 為了減少應(yīng)用的初始化時(shí)間羞酗;
????????處理 A/B 測(cè)試,比如測(cè)試各種算法的不同實(shí)現(xiàn)紊服;
????????加載很少會(huì)使用到的功能檀轨,比如可選的屏幕和對(duì)話框。
? ??????使用?deferred as?關(guān)鍵字?來(lái)標(biāo)識(shí)需要?延時(shí)加載?的代碼庫(kù):
? ??????????import 'package:greetings/hello.dart' deferred as hello;
? ??????當(dāng)實(shí)際需要使用到庫(kù)中 API 時(shí)先調(diào)用?loadLibrary?函數(shù)加載庫(kù):
? ??????使用?await?關(guān)鍵字?暫停代碼執(zhí)行?直到庫(kù)加載完成欺嗤;
? ??????loadLibrary?函數(shù)可以調(diào)用多次也沒(méi)關(guān)系参萄,代碼庫(kù)?只會(huì)被加載一次 (和 js 中 require 類似)。
? ? 注意:
? ??????當(dāng)你使用延遲加載的時(shí)候需要牢記以下幾點(diǎn):
? ? ? ? 1 延遲加載的代碼庫(kù)中的常量需要在代碼庫(kù)被加載的時(shí)候才會(huì)導(dǎo)入煎饼,未加載時(shí)是不會(huì)導(dǎo)入的;
? ? ? ? 2 導(dǎo)入文件的時(shí)候無(wú)法使用延遲加載庫(kù)中的類型讹挎。如果你需要使用類型,則考慮把接口類型轉(zhuǎn)移到另一個(gè)庫(kù)中然后讓兩個(gè)庫(kù)都分別導(dǎo)入這個(gè)接口庫(kù);
? ? ? ? 3 Dart會(huì)隱式地將?loadLibrary()?導(dǎo)入到使用了?deferred as?命名空間?的類中吆玖。?loadLibrary()?函數(shù)返回的是一個(gè) Future筒溃。
異步支持
????Dart 代碼庫(kù)中有大量返回?Future?或?Stream?對(duì)象的函數(shù),這些函數(shù)都是異步的沾乘,它們會(huì)在耗時(shí)操作(比如I/O)執(zhí)行完畢前直接返回而不會(huì)等待耗時(shí)操作執(zhí)行完畢怜奖。
? ??async?和?await?關(guān)鍵字用于實(shí)現(xiàn)異步編程,并且讓你的代碼看起來(lái)就像是同步的一樣(同 JS)翅阵。
????Future
? ? 在 Dart 庫(kù)中隨處可見(jiàn) Future 對(duì)象歪玲,通常異步函數(shù)返回的對(duì)象就是一個(gè) Future迁央。當(dāng)一個(gè) future完成執(zhí)行后,future 中的值就已經(jīng)可以使用了滥崩, 如何使用 future 的值(和 JS 類似):
? ? 1 使用?async?和?await岖圈;
? ??? ??async?函數(shù)能夠捕獲來(lái)自 Future 的異常;
? ??2 使用 Future API夭委, then 語(yǔ)法幅狮;
? ??????使用?catchError()?來(lái)處理一些 Future 對(duì)象可能拋出的錯(cuò)誤或者異常;
? ??????then().catchError()?組合是?try-catch?的異步版本株灸。
鏈?zhǔn)疆惒骄幊?/b>
? ??????then()?方法返回一個(gè) Future 對(duì)象崇摄,這樣就提供了一個(gè)非常好的方式讓多個(gè)異步方法按順序依次執(zhí)行。如果用?then()?注冊(cè)的回調(diào)返回一個(gè) Future 慌烧,那么?then()?返回一個(gè)等價(jià)的 Future 逐抑。如果回調(diào)返回任何其他類型的值,那么?then()?會(huì)創(chuàng)建一個(gè)以該值完成的新 Future屹蚊;
等待多個(gè) Future
? ? 類似 promise.all
Stream
? ??在 Dart API 中 Stream 對(duì)象隨處可見(jiàn)厕氨,Stream 用來(lái)表示一系列數(shù)據(jù)。例如汹粤,HTML 中的按鈕點(diǎn)擊就是通過(guò) stream 傳遞的命斧。同樣也可以將文件作為數(shù)據(jù)流來(lái)讀取。
? ??異步循環(huán)
? ??????它使用 Stream 的?listen()?方法來(lái)訂閱文件列表嘱兼,傳入一個(gè)搜索文件或目錄的函數(shù);
? ????有時(shí)国葬,可以使用異步 for 循環(huán)?await for?,來(lái)替代 Stream API 芹壕。
????監(jiān)聽(tīng)流數(shù)據(jù)(stream data)
? ??????使用?await for?或者使用?listen()?方法監(jiān)聽(tīng) stream汇四,來(lái)獲取每個(gè)到達(dá)的數(shù)據(jù)流值:
? ??傳遞流數(shù)據(jù)(stream data)
? ??????在使用流數(shù)據(jù)前需要改變數(shù)據(jù)的格式,使用?transform()?方法生成具有不同類型數(shù)據(jù)的流:
? ??????如果使用的是 Stream API踢涌,那么通過(guò)注冊(cè)?onError?監(jiān)聽(tīng)來(lái)處理錯(cuò)誤通孽。代碼位于注冊(cè)的?onDone?中,會(huì)在 stream 被關(guān)閉后執(zhí)行睁壁;