【Flutter】利用Future封裝出js中的Promise

前端的同學對Promise肯定都很熟悉,而Future便是dartPromise,但方法名稱和使用方式還是有些許的差異的。
下面我們嘗試塞栅,利用Future封裝出js中我們熟悉的Promise

Javascript Promise 參考

https://es6.ruanyifeng.com/#docs/promise

實現(xiàn)Promise的基本用法

import 'dart:async';

class Promise {
  Future future;

  Promise(dynamic excutor(dynamic resolve(val), dynamic reject(val))) {
    if (!(excutor is Function)) {
      throw new AssertionError('Promise resolver $excutor is not a function');
    }
    final completer = Completer();
    try {
      excutor(completer.complete, completer.completeError);
    } catch (e) {
      completer.completeError(e);
    }
    this.future = completer.future;
  }

  /// Promise鏈式回調(diào)腔丧,對應Dart [.then]
  Future then(Future Function(dynamic) onValue, {Function onError}) {
    return this.future?.then(onValue, onError: onError);
  }

  /// Promise鏈式回調(diào)放椰,對應Dart [.catchError]
  Future catch_(Function onError, {bool Function(Object) test}) {
    return this.future?.catchError(onError, test: test);
  }

  /// Promise鏈式回調(diào)作烟,對應Dart [.whenComplete]
  Future finally_(Future<dynamic> Function() action) {
    return this.future?.whenComplete(action);
  }
}

使用示例

Promise promise = Promise((resolve,reject){
  // ... some code

  if (/* 異步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
})

// 鏈式回調(diào)
promise
   .then((value) => null)
   .catch_((error) => null)
   .finally_((action) => null);

// 如果要使用dart的 async/await 需要先獲取到 Promise 實例內(nèi)的 Future
dynamic result = await promise.future;

Futrue中有對應實現(xiàn)的方法

Promise.all, Promise.race, Promise.resolve, Promise.reject

class Promise{
  /// 用于將多個 Future 實例,包裝成一個新的 Future 實例砾医。
  /// 等待[futures]完成并收集其結(jié)果拿撩。
  static Future all(Iterable<Future> futures) => Future.wait(futures);

  /// 對應Dart [Future.any]
  /// 返回[futures]中成功完成的第一個future的結(jié)果。
  /// 任意失敗都會導致拋出異常
  static Future race(Iterable<Future> futures) => Future.any(futures);

  /// 對應Dart [Future.value]
  static Future resolve(dynamic value) => Future.value(value);

  /// 對應Dart [Future.error]
  static Future reject(dynamic value) => Future.error(value);
}

Futrue中有無對應實現(xiàn)的方法

Promise.allSettled方法接受一組 Promise 實例作為參數(shù)藻烤,包裝成一個新的 Promise 實例绷雏。只有等到所有這些參數(shù)實例都返回結(jié)果,不管是fulfilled還是rejected怖亭,包裝實例才會結(jié)束。該方法由 ES2020 引入

class Promise{
  static final String FULFILLED = 'fulfilled';
  static final String REJECTED = 'rejected';

  /// 用于將多個 Future 實例坤检,包裝成一個新的 Future 實例兴猩。
  /// 不論成功失敗,都返回結(jié)果
  static Future allSettled(Iterable<Future> futures) {
    List<dynamic> result = List.generate(futures.length, (index) => null);
    final completer = Completer();

    for (int i = 0; i < futures.length; i++) {
      futures.elementAt(i).then((value) {
        result[i] = {'status': FULFILLED, 'value': value};
      }).catchError((error) {
        result[i] = {'status': REJECTED, 'reason': error};
      }).whenComplete(() {
        if (result.every((element) => element != null)) {
          return completer.complete(result);
        }
      });
    }

    return completer.future;
  }
}

Promise.any()方法接受一組 Promise 實例作為參數(shù)早歇,包裝成一個新的 Promise 實例倾芝。只要參數(shù)實例有一個變成fulfilled狀態(tài),包裝實例就會變成fulfilled狀態(tài)箭跳;如果所有參數(shù)實例都變成rejected狀態(tài)晨另,包裝實例就會變成rejected狀態(tài)。該方法目前是一個第三階段的提案 谱姓。

Promise.any()Promise.race()方法很像借尿,只有一點不同,就是不會因為某個 Promise 變成rejected狀態(tài)而結(jié)束屉来。

class Promise{
  /// 返回[futures]中成功完成的第一個future的結(jié)果;
  /// 全部失敗才會拋出異常
  /// ```
  /// @param futures {Iterable<Future>} Future 實例組
  /// @param onlyError {bool} 是否只拋出最后一個異常結(jié)果路翻,否則拋出一個異常 List ,默認 false
  /// ```
  static Future any(Iterable<Future> futures, {bool onlyError = false}) async {
    List<dynamic> errors = [];
    final completer = Completer();

    for (int i = 0; i < futures.length; i++) {
      futures.elementAt(i).then((value) {
        completer.complete(value);
      }).catchError((error) {
        errors[i] = error;
        if (futures.length == errors.length) {
          completer.completeError(onlyError ? error : errors);
        }
      });
    }

    return completer.future;
  }
}

順便把延遲函數(shù)也封裝一下茄靠,畢竟毫秒延遲的使用頻率是最高的茂契。

class Promise{
  static Future sleep(int ms) => Future.delayed(Duration(milliseconds: ms));
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市慨绳,隨后出現(xiàn)的幾起案子掉冶,更是在濱河造成了極大的恐慌,老刑警劉巖脐雪,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厌小,死亡現(xiàn)場離奇詭異,居然都是意外死亡喂江,警方通過查閱死者的電腦和手機召锈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來获询,“玉大人涨岁,你說我怎么就攤上這事拐袜。” “怎么了梢薪?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵蹬铺,是天一觀的道長。 經(jīng)常有香客問我秉撇,道長甜攀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任琐馆,我火速辦了婚禮规阀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瘦麸。我一直安慰自己谁撼,他們只是感情好,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布滋饲。 她就那樣靜靜地躺著厉碟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屠缭。 梳的紋絲不亂的頭發(fā)上箍鼓,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天,我揣著相機與錄音呵曹,去河邊找鬼款咖。 笑死,一個胖子當著我的面吹牛逢并,可吹牛的內(nèi)容都是我干的之剧。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼砍聊,長吁一口氣:“原來是場噩夢啊……” “哼背稼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起玻蝌,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蟹肘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俯树,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帘腹,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年许饿,在試婚紗的時候發(fā)現(xiàn)自己被綠了阳欲。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖球化,靈堂內(nèi)的尸體忽然破棺而出秽晚,到底是詐尸還是另有隱情,我是刑警寧澤筒愚,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布赴蝇,位于F島的核電站,受9級特大地震影響巢掺,放射性物質(zhì)發(fā)生泄漏句伶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一陆淀、第九天 我趴在偏房一處隱蔽的房頂上張望考余。 院中可真熱鬧,春花似錦轧苫、人聲如沸秃殉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鳄袍,卻和暖如春绢要,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拗小。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工重罪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哀九。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓剿配,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阅束。 傳聞我的和親對象是個殘疾皇子呼胚,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

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

  • 原創(chuàng)性聲明:本文完全為筆者原創(chuàng),請尊重筆者勞動力息裸。轉(zhuǎn)載務必注明原文地址蝇更。 發(fā)現(xiàn)有一段時間沒有寫文章了,中了一段時間...
    東方一號藍閱讀 691評論 0 1
  • 你不知道JS:異步 第三章:Promises 接上篇3-1 錯誤處理(Error Handling) 在異步編程中...
    purple_force閱讀 1,391評論 0 2
  • 1. Promise 的含義 所謂Promise呼盆,簡單說就是一個容器年扩,里面保存著某個未來才會結(jié)束的事件(通常是一個...
    ROBIN2015閱讀 484評論 0 0
  • 本文是整理阮一峰大神ES6中 Promise 的學習筆記 目錄: Promise.prototype.then()...
    叫我王必過閱讀 242評論 0 2
  • 早上上班時,有搞售后的張師來辦公室串門访圃。 因問起他最近的一筆生意厨幻,他說應該問題不大。我遂與他開玩笑說:...
    雪里梅香閱讀 263評論 1 1