1. 程式人生 > >bluebird與原生Promise物件及bluebird模組的中文API文件

bluebird與原生Promise物件及bluebird模組的中文API文件

bluebird與原生Promise物件及bluebird模組的中文API文件

 2016年06月15日     9392     宣告


https://itbilu.com/nodejs/npm/VJHw6ScNb.html#api-promise.try


Promise物件已在ECMAScript 2015中被寫入標準,且已被最新版本的瀏覽器和Node.js/IO.js所支援。bluebird是一個第三方Promise規範實現庫,它不僅完全相容原生Promise物件,且比原生物件功能更強大。

  1. 相關介紹
  2. 主要API

相關介紹

bluebirdPromise

JavaScript中有很多第三方的Promise庫,在ECMAScript 2015(ES 6)中也實現了一個Promise物件,可以在最新版本的瀏覽器和Node.js/IO.js中使用。

bluebird同樣是一個第三方Promise類庫,相比其它第三方類庫或標準物件來說,其有以下優點:功能更齊全而不臃腫、瀏覽器相容性更好。


Promise物件

Promise物件已在ECMAScript 2015中做為JavaScript的標準內建物件提供,這個物件根據Promise A+

規範實現,相對比較簡單。除從Object物件中繼承物件屬性/方法外,它還有以下Promise自身的屬性/方法。簡單介紹如下:

Promise中的類方法

JavaScript中的類(物件)方法可以認為是靜態方法(即:不需要例項化就可以使用的方法)。Promise中有以下類方法:

  • Promise.all(promiseArray) - 將多個Promise例項包裝成一個新例項,多個例項會同時執行成功或失敗
  • Promise.race(promiseArray) - 將多個Promise例項包裝成一個新例項,例項中的任何一個例項執行成功或失敗將返回
  • Promise.resolve(obj)
     - 將物件包裝成resolve狀態的Promise例項
  • Promise.reject(obj) - 將物件包裝成reject狀態的Promise例項

Promise中的例項方法

例項方法,是指建立Promise例項後才能使用的方法,即:被新增到原型鏈Promise.prototype上的方法。Promise中有以下例項方法:

  • promise.then(onFulfilled, onRejected) - 執行成功(或/與)失敗的處理
  • promise.catch(onRejected) - 執行失敗的處理

Promise A+規範規定:每個Promise例項中返回的都應該是一個Promise例項或thenable物件。基於這個特性,能夠實現類似於同步的鏈式呼叫

Promise物件詳細介紹


bluebird模組

bluebird是一個第三方的Promise實現,我們可通過npm命令來安裝:

npm install bluebird

模組安裝後,可以就可以通過require獲取對模組的引用:

var Promise = require('bluebird');

bluebird模組除Promise物件中的方法外,還有很多擴充套件方法。如,可以通過.spread()展開結構集、可以通過Promise.promisify()方法將一個Node回撥函式包裝成一個Promise例項。


bluebird中主要API如下:

  1. 核心(Core)
  2. 同步檢查(Synchronous inspection)
  3. 集合操作(Collections)
  4. 資源管理(Resource management)
  5. Promise包裝器(Promisification)
  6. 定時器(Timers)
  7. 工具方法(Utility)


1. 核心方法(Core)

核心方法包括Promise例項和Promise物件中的核心靜態方法。

1.1 new Promise - 建立例項

new Promise(function(function resolve, function reject) resolver) -> Promise

該方法是一個建構函式,用於建立一個新的Promise例項。該方法與Promise A+規範實現一致,傳入的函式引數中有兩個引數:resolvereject,這兩個引數被封裝到所建立的Promise例項中,分別用於執行成功和執行失敗時的呼叫。

如,我們可以將XMLHttpRequest物件AJAX請求封裝成一個Promise物件:

function ajaxGetAsync(url) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest;
    xhr.addEventListener("error", reject);
    xhr.addEventListener("load", resolve);
    xhr.open("GET", url);
    xhr.send(null);
  });
}

然後我就可以像下面這樣進行AJAX請求:

ajaxGetAsync('http://itbilu.com')
.then(function(result){
  // 請求成功的處理
})
.catch(function(err){
  // 請求失敗的處理	
})

在使用Promise進行處理時,要確保每一步都要返回一個Promise例項,並進行鏈式處理。如果不能立即開始一個Promise鏈式處理,可以使用new Promise來構造一個例項:

function getConnection(urlString) {
  return new Promise(function(resolve) {
    //不使用 new Promise時,這裡會顯式的丟擲一個異常
    var params = parse(urlString);
    resolve(getAdapter(params).getConnection());
  });
}


1.2 .then - 例項的then()方法

.then(
  [function(any value) fulfilledHandler],
  [function(any error) rejectedHandler]
) -> Promise

Promise A+ 規範中的.then()方法,該方法可以同時傳入用於操作成功後呼叫的fulfilledHandler回撥函式和用於操作失敗後呼叫的rejectedHandler回撥函式,也可以只傳入其中的一個。

參考:Promise 物件的例項方法


1.3 .spread - 展開例項返回的結果陣列

.spread(
  [function(any values...) fulfilledHandler]
) -> Promise

類似呼叫.then方法,但執行成功後的值(fulfillment值)必須是一個數組,它會將引數扁平化並分別呼叫fulfilledHandler處理函式。

Promise.delay(500).then(function() {
  return [fs.readFileAsync("file1.txt"),
         fs.readFileAsync("file2.txt")] ;
}).spread(function(file1text, file2text) {
  if (file1text !== file2text) {
    console.log("files are equal");
  } else {
    console.log("files are not equal");
  }
});

而使用ES 6規範進行處理時,可以像下面這樣操作:

Promise.delay(500).then(function() {
  return [fs.readFileAsync("file1.txt"),
         fs.readFileAsync("file2.txt")] ;
}).all().then(function([file1text, file2text]) {
  if (file1text !== file2text) {
    console.log("files are equal");
  } else {
    console.log("files are not equal");
  }
});

注意:.spread()方法會隱式的呼叫.all()方法,而在ES6中要顯式的呼叫。


1.4 .catch - 例項異常處理方法

.catch是Promise鏈式處理中的用於異常處理的便捷方法。這個方法有兩個變體:一個用於捕獲所有錯誤,類似catch(e) {的同步方法;一個是用於捕獲指定錯誤的變體方法。

promise中的異常捕獲

function getItems(param) {
  return getItemsAsync().then(items => {
    if(!items) throw new InvalidItemsError(); 
    return items;
  }).catch(e => {
    // 從 getItemsAsync 中返回一個 rejects 或 假值時,可以從這裡解決和恢復錯誤
    throw e; 
    // Need to rethrow unless we actually recovered, just like in the synchronous version
  }).then(process);
}

捕獲所有異常

.catch(function(any error) handler) -> Promise
.caught(function(any error) handler) -> Promise

捕獲所有異常是promise中.then(null, handler)的便捷方法,.then鏈中異常會被傳遞到.catch中。

為了能和ECMASript早期版本相容,為.catch添加了一個別名方法.caught

捕獲部分異常

.catch(
  class ErrorClass|function(any error)|Object predicate...,
  function(any error) handler
) -> Promise
.caught(
  class ErrorClass|function(any error)|Object predicate...,
  function(any error) handler
) -> Promise

部分捕獲類似Java或C#中的catch分句,可以通過錯誤建構函式來進行異常的捕獲處理。

somePromise.then(function() {
  return a.b.c.d();
}).catch(TypeError, function(e) {
  //If it is a TypeError, will end up here because
  //it is a type error to reference property of undefined
}).catch(ReferenceError, function(e) {
  //Will end up here if a was never declared at all
}).catch(function(e) {
  //Generic catch-the rest, error wasn't TypeError nor
  //ReferenceError
});

也可以在一個.catch分句中捕獲多個錯誤:

somePromise.then(function() {
  return a.b.c.d();
}).catch(TypeError, ReferenceError, function(e) {
  //Will end up here on programmer error
}).catch(NetworkError, TimeoutError, function(e) {
  //Will end up here on expected everyday network errors
}).catch(function(e) {
  //Catch any unexpected errors
});


1.5 .error - 例項操作異常處理

.error([function(any error) rejectedHandler]) -> Promise

類似.catch,但它只捕獲和處理操作錯誤。

.catch處理相比:

// 假定會全域性觸發一個 OperationalError 異常
function isOperationalError(e) {
    if (e == null) return false;
    return (e instanceof OperationalError) || (e.isOperational === true);
}

// catch 捕獲
.catch(isOperationalError, function(e) {
    // ...
})

// 等價於:
.error(function(e) {
    // ...
});

如,我們可能希望捕獲JSON.parse引發的SyntaxError錯誤和fs檔案操作相關錯誤,可以像下面這樣傳遞處理錯誤:

var fs = Promise.promisifyAll(require("fs"));

fs.readFileAsync("myfile.json").then(JSON.parse).then(function (json) {
  console.log("Successful json")
}).catch(SyntaxError, function (e) {
  console.error("file contains invalid json");
}).error(function (e) {
  console.error("unable to read file, because: ", e.message);
});


1.6 .finally - 例項最終呼叫方法

.finally(function() handler) -> Promise
.lastly(function() handler) -> Promise

這個方法不會考慮Promise例項的執行狀態,而始終會呼叫並返回一個新promise鏈。

考慮如下一個處理:

function anyway() {
  $("#ajax-loader-animation").hide();
}

function ajaxGetAsync(url) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest;
    xhr.addEventListener("error", reject);
    xhr.addEventListener("load", resolve);
    xhr.open("GET", url);
    xhr.send(null);
  }).then(anyway, anyway);
}

在上在操作中,我們期望的操作是無論執行結果如果,都要將元素隱藏,這樣我們需要在.then鏈的兩種執行狀態中分別傳入隱藏方法。

這種情況非常適合使用.finally處理:

function ajaxGetAsync(url) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest;
    xhr.addEventListener("error", reject);
    xhr.addEventListener("load", resolve);
    xhr.open("GET", url);
    xhr.send(null);
  }).finally(function() {
    $("#ajax-loader-animation").hide();
  });
}


1.7 Promise.join - 關聯多個不相關的例項

Promise.join(
  Promise<any>|any values...,
  function handler
) -> Promise

關聯多個不相關的Promise例項。.all很適合處理統一處理動態大小的列表,而.join使處理多個離散的Promise例項處理更加容易。

在這個方法,方法的最後一個引數是一個回撥函式,其中包含所有的處理成功的結果:

var Promise = require("bluebird");
var join = Promise.join;

join(getPictures(), getComments(), getTweets(),
  function(pictures, comments, tweets) {
    console.log("in total: " + pictures.length + comments.length + tweets.length);
});


1.8 Promise.try - 包裝為Promise例項

Promise.try(function() fn) -> Promise
Promise.attempt(function() fn) -> Promise

通過Promise.try啟動一個promise鏈,並將所有同步異常封裝到promise的reject處理中:

function getUserById(id) {
  return Promise.try(function() {
    if (typeof id !== "number") {
      throw new Error("id must be a number");
    }
    return db.getUserById(id);
  });
}

在上面示例中,經過Promise.try封裝後,其同步和非同步異常都可以通過.catch來捕獲。


1.9 Promise.method - 將函式包裝為返回Promise例項的函式

Promise.method(function(...arguments) fn) -> function

包裝指定的函式fn,包裝後函式會返回一個Promise例項。

如,對於如下一個不使用Promise.method包裝的方法:

MyClass.prototype.method = function(input) {
  if (!this.isValid(input)) {
    return Promise.reject(new TypeError("input is not valid"));
  }

  if (this.cache(input)) {
    return Promise.resolve(this.someCachedValue);
  }

  return db.queryAsync(input).bind(this).then(function(value) {
    this.someCachedValue = value;
    return value;
  });
};

通過Promise.method對包裝以方法時:

MyClass.prototype.method = Promise.method(function(input) {
  if (!this.isValid(input)) {
    throw new TypeError("input is not valid");
  }

  if (this.cache(input)) {
    return this.someCachedValue;
  }

  return db.queryAsync(input).bind(this).then(function(value) {
    this.someCachedValue = value;
    return value;
  });
});


1.10 Promise.resolve - 包裝值為Promiseresolved例項

Promise.resolve(Promise<any>|any value) -> Promise

通過指定值建立Promiseresolved例項。如果值已使用Promise,那會返回它。如果值不是thenable物件,會將其包裝成一個會執行成功的Promise例項,該值將會做為fulfillment值返回。

Promise.resolve($.get("http://www.google.com")).then(function() {
  // 從處理函式中返回一個thenable,按Promises/A+ 規範自動載換為可信的Promise 
  return $.post("http://www.yahoo.com");
}).then(function() {

}).catch(function(e) {
  //jQuery 不會丟擲真的錯誤,所以使用 catch-all
  console.log(e.statusText);
});


1.11 Promise.reject - 包裝值為Promisereject例項

Promise.reject(any error) -> Promise

將指定的值包裝為一個

相關推薦

bluebird原生Promise物件bluebird模組中文API

bluebird與原生Promise物件及bluebird模組的中文API文件  2016年06月15日     9392     宣告 https://itbilu.com/nodejs/np

簡單 web 服務客戶端開發實戰 複製SWAPI網站 api

專案github地址如下 https://github.com/BigBrother3 本篇文件主要是展示一下專案中的api 查詢資源api 直接用get請求 http://localhost:8080/api/films/1 ,就可以得到資源。 資源的api主要有 總的a

Fiddler2介紹使用和中文幫助(1)

Fiddler2 主選單 六個主選單分別是: 檔案(File) Capture Traffic ——啟用捕獲功能,快捷鍵 F12 此功能的開啟/關閉狀態,程式安裝後預設是開啟的。可以在 Fiddler 底部狀態列最左側看到:(開啟狀態)、(關閉狀態) 也可以通過滑鼠點選狀態列該圖示來進行切換。 Load A

Django Rest React(Django2.1 + coverage測試 + xadmin + 線上api)-翻譯實踐強化版

原文: www.valentinog.com/blog/tutori… 翻譯版實踐教程: Django Rest 與 React(Django2.1 加 一點小測試 加一點譯者的小額外功能) 最終構建了一個有後臺管理 + 提供api服務 + Mysql資料庫 + 線上api文件的Lead系統。

Sequelize 中文API-6. 事務的使用Transaction類

Transaction是Sequelize中用於實現事務功能的子類,通過呼叫Sequelize.transaction()方法可以建立一個該類的例項。在Sequelize中,支援自動提交/回滾,也可以支援使用者手動提交/回滾。1. 事務的使用Sequelize有兩種使用事務的

Swagger UI Swagger editor教程 API搭配 Node使用

swagger ui 是一個線上文件生成和測試的利器,目前發現最好用的. 支援API自動生成同步的線上文件些文件可用於專案內部API稽核方便測試人員瞭解 API這些文件可作為客戶產品文件的一部分進行

python中os模組中文幫助

這個模組提供了一個輕便的方法使用要依賴作業系統的功能。 如何你只是想讀或寫檔案,請使用open() ,如果你想操作檔案路徑,請使用os.path模組,如果你想在命令列中,讀入所有檔案的所有行,請使用 fileinput模組。使用tempfile模組建立臨

Android中Webview原生介面互動二維碼掃描功能實現

最近專案中有一個新的需求,大致是這樣的:APP中通過WebView展示一個第三方的HTML5介面,使用者可以在HTML5介面中呼叫Android攝像頭進行二維碼掃描,並將掃描結果顯示在HTML5介面。這顯然涉及到了Android原生與WebView之前的傳值

ubuntu下useraddadduser差別,新建用戶不再home夾下

net tle title ubuntu下 home forum .net useradd ng- useradd username不會在/home下建立一個目錄username adduser username會在/home下建立一個目錄username us

python jsonmysql——讀取json存sql、數據庫日期類型轉換、終端操縱mysqlpython codecs讀取大問題

temp extra log urn xtra mysql 程序 pre 安裝mysql preface: 近期幫師兄處理json文件,須要讀到數據庫裏面,以備其興許從數據庫讀取數據。數據是關於yelp站點裏面的: https://github.com/Yelp/d

springboot整合mybatis封裝curd操作-配置

enabled () init tps github mys tde oos maven 1 配置文件 application.properties #server server.port=8090 server.address=127.0.0.1 server.ses

系統基礎ext系統創建管理詳解、系統的使用卸載、fstab格式自動掛載系統的

文件系統創建文件系統--分區格式化 格式化: 低級格式化: 劃分磁道 高級格式化: 創建文件系統,按照某種特定的標準,將整個分區劃分為大小相同的若幹小的邏輯編址單元,每個這樣的單元稱為塊(block)【windows中稱為簇】; 劃分塊的標準: 在Linux的文件系統中,主要的塊的劃分

Linux用戶用戶組配置 時間戳

用戶及用戶組配置文件 時間戳Linux系統下賬戶文件主要有/etc/passwd,/etc/shadow,/etc/group,/etc/gshadow四個文件,其中和用戶相關的文件/etc/passwd用戶配置文件,/etc/shadow影子口令文件,和用戶組相關的文件/etc/group,/etc/

java--基本數據類型String寫出到

rgs dos 基本數據 path buffere red ctu ast output package com.machuang.io.others; import java.io.BufferedOutputStream; import java.io.DataOu

python 中文輸入輸出os模塊對系統的操作

imp 合成 接受 信息 sdi pick close 指針 方法 整理了一下python 中文件的輸入輸出及主要介紹一些os模塊中對文件系統的操作。 文件輸入輸出 1、內建函數open(file_name,文件打開模式,通用換行符支持),打開文件返回文件對象。 2、對打開

微理財玖富小金票介面對接專案

  微理財與玖富小金票介面對接需求說明書   版本 日期 作者 審批 V1.3 2015-03-25 姚國亮  

golang log模組之log4go

介紹 這個儲存庫是從alecthomas的log4go重構而來的,log4go是一個日誌包,類似於Go程式語言的log4j。 支援兩個新特性,一個是Json配置樣式,另一個是根據類別的不同輸出。 特點 記錄到控制檯 日誌檔案,支援按大小或時間旋轉。 登入

layui.table模組/資料表格

Layui_table模組/資料表格文件  table 模組是我們的又一走心之作,在 layui 2.0 的版本中全新推出,是 layui 最核心的組成之一。它用於對錶格進行一些列功能和動態化資料操作,涵蓋了日常業務所涉及的幾乎全部需求。支援固定表頭、固定行、固定列左

springboot打包去除資源啟動時指定配置位置

jar包 exc plugins spa oot clu amp 一起 ssp springboot打包時,去掉資源文件,可按照如下配置 <build> <resources> <resource>

結合Doc2Vec改進聚類演算法的中文自動摘要方法研究

                                                                      圖1 本文方法示意圖 一.基於Doc2Vec 的句子向量訓練        Doc2Vec 模型能很好地結合上下文語境, 挖