Completer 與 FutureBuilder 異步創(chuàng)建組件

在日常的開發(fā)中經(jīng)常會遇到二次請求才能完成顯示的情況

舉一個比較典型的例子:listView中的數(shù)據(jù)是下方的格式

[{String imgId,String text},{String imgId,String text}...]

需要使用imgId獲取具體的圖片url,這里就會有同學(xué)舉手了:為啥不直接給我一個url

因為這里不是單純的獲取一個url而已,一般是一個圖片對象汉规,然后客戶端根據(jù)不同的情況使用不同的圖片(類似的還有訂單Id等)

在原生Android中這個問題根本就不是個問題哭尝,在Adapter中再次進(jìn)行網(wǎng)絡(luò)請求(一般不會直接在Adapter中做這種事情,這里只是舉個例子)并對ImageView進(jìn)行賦值即可依疼,

但是基于狀態(tài)的Flutter做不到這一點痰腮,Widget是不可變的,沒法對其進(jìn)行再次賦值律罢,而且build()方法是不接受Future類型返回值的膀值,不能異步返回

這個有幾個辦法用來解決這個問題:

  1. 在本地額外加一個參數(shù)用來保存返回后的數(shù)據(jù),在返回后調(diào)用setState()進(jìn)行數(shù)據(jù)的保存
    這樣也不是說不行误辑,但是至少會存在問題:

    1. 什么時候進(jìn)行setState的調(diào)用沧踏,如果每張圖片完成后都進(jìn)行setState,那么setState次數(shù)過多消耗就會很大巾钉,如果加載完成后setState那么就需要用戶等待所有圖片都下載成功才能看到圖片翘狱,而且還需要額外的操作判斷所有請求都完成

    2.如果數(shù)據(jù)類型很多的話需要添加的參數(shù)就太多了,數(shù)據(jù)結(jié)構(gòu)過于冗余

2.僅使用FutureBuilder<T>
FutureBuilder是一個異步組件砰苍,顧名思義潦匈,可以通過一個feature來進(jìn)行組件的創(chuàng)建

/// Creates a widget that builds itself based on the latest snapshot of
/// interaction with a [Future].
///
/// The [builder] must not be null.
const FutureBuilder({
  Key key,
  this.future,
  this.initialData,//與創(chuàng)建時的泛型相同
  @required this.builder,//AsyncWidgetBuilder<T> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot);
}) : assert(builder != null),
     super(key: key);

initialData是在feature未完成時該組件的值,這里不是必要的赚导,但默認(rèn)值為null茬缩,需要注意處理
builder中的 snapshot參數(shù)為feture返回時的數(shù)據(jù)包裝類,使用 snapshot.data 進(jìn)行數(shù)據(jù)的獲取吼旧,該類還具有withError等方法用來處理意外情況

由于項目中使用 MVP 進(jìn)行開發(fā)凰锡,邏輯部分需要在Presenter層中進(jìn)行處理,以一個圖片例如:

//presenter
@override
  Future<Widget> requestImageDetail(String imageId) async{
    var image = await _imModel.getImageDetail(await PublicParams.getParams()..["image_id"] = imageId);
    var url = image!=null?image[0].imageMiddle:"";
    return Future.value(ImageUtil.network(url));
  }
//view
FutureBuilder(initialData:Image.asset(Constant.IMAGE_ICON_LIFE),
  future:requestImageDetail(imageId),
  builder: (BuildContext context, AsyncSnapshot<Widget> snapshot){
    return snapshot.data;
},)

代碼很簡單,這個方法的返回值直接用作FutureBuilder的future即可寡夹,這個Future會直接完成处面。

這段代碼雖然可以完成需求,但是對于MVP產(chǎn)生了嚴(yán)重的破壞菩掏,

首先魂角,P層的方法不應(yīng)該有返回值,

其次智绸,在本項目中model層應(yīng)該返回的是 StreamSubscription野揪,用來監(jiān)聽Stream返回并可以斷開監(jiān)聽,而在這里返回Future的話導(dǎo)致這個方法跳出了“三界”而不受管控

所以比較好的辦法是使用Completer與FutureBuilder進(jìn)行配合

  1. 使用Completer<T>與FutureBuilder進(jìn)行配合
    Completer<T>是與Future相關(guān)的一個類瞧栗,調(diào)用Completer.complete(T)進(jìn)行手動進(jìn)行Future的返回

需要對上面的代碼進(jìn)行一些修改

//view
Completer<Image> _image = Completer();
mPresenter.requestImageDetail(_image, imageId);
FutureBuilder(initialData:Image.asset(Constant.IMAGE_ICON_LIFE),
  future:_image.future,
  builder: (BuildContext context, AsyncSnapshot<Widget> snapshot){
    return snapshot.data;
},)
  
//presenter
requestImageDetail(Completer completer, String imageId) async{
  makeRequest(_imModel.getImageDetail(await PublicParams.getParams()..["image_id"] = imageId,ICallBack<List<ImageInfoEntity>>(
      (image){
        var url = image!=null?image[0].imageMiddle:"";
        completer.complete(ImageUtil.network(url));
      }
  )));
}

以上

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斯稳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子迹恐,更是在濱河造成了極大的恐慌挣惰,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件殴边,死亡現(xiàn)場離奇詭異憎茂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锤岸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門竖幔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人是偷,你說我怎么就攤上這事拳氢。” “怎么了蛋铆?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵馋评,是天一觀的道長。 經(jīng)常有香客問我刺啦,道長留特,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任洪燥,我火速辦了婚禮磕秤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捧韵。我一直安慰自己市咆,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布再来。 她就那樣靜靜地躺著蒙兰,像睡著了一般磷瘤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上搜变,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天采缚,我揣著相機(jī)與錄音,去河邊找鬼挠他。 笑死扳抽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的殖侵。 我是一名探鬼主播贸呢,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拢军!你這毒婦竟也來了楞陷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤茉唉,失蹤者是張志新(化名)和其女友劉穎固蛾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體度陆,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡艾凯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了坚芜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片览芳。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡斜姥,死狀恐怖鸿竖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铸敏,我是刑警寧澤缚忧,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站杈笔,受9級特大地震影響闪水,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蒙具,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一球榆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧禁筏,春花似錦持钉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽始腾。三九已至,卻和暖如春空执,著一層夾襖步出監(jiān)牢的瞬間浪箭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工辨绊, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留奶栖,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓门坷,卻偏偏與公主長得像驼抹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拜鹤,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

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