promise設計模式

Mr清歌發表於2018-03-05

promise出現的動機

在javascript的世界中,所有程式碼都是單執行緒執行的。
由於這個缺陷,導致所有的的網路操作,瀏覽器事件都是由非同步執行。非同步執行可以用回撥實現,ajax就是典型的非同步操作

如下程式碼在純JavaScript中實現它們並使用它們來包裝現有的非同步操作:

function readJSON(filename, callback){
  fs.readFile(filename, 'utf8', function (err, res){
    if (err) return callback(err);
    try {
      res = JSON.parse(res);
    } catch (ex) {
      return callback(ex);
    }
    callback(null, res);
  });
}
複製程式碼

以上程式碼缺點有很多,實現多次回撥會使我們的程式碼變得非常混亂。

promise描述

promise(承諾)承諾背後的核心思想是承諾代表非同步操作的結果。

一個 Promise有以下幾種狀態:

  • pending: 初始狀態,既不是成功,也不是失敗狀態。
  • fulfilled: 意味著操作成功完成。
  • rejected: 意味著操作失敗。

pending 狀態的 Promise 物件可能觸發fulfilled 狀態並傳遞一個值給相應的狀態處理方法,也可能觸發失敗狀態(rejected)並傳遞失敗資訊。當其中任一種情況出現時,Promise 物件的 then 方法繫結的處理方法(handlers )就會被呼叫(then方法包含兩個引數:onfulfilled 和 onrejected,它們都是 Function 型別。當Promise狀態為fulfilled時,呼叫 then 的 onfulfilled 方法,當Promise狀態為rejected時,呼叫 then 的 onrejected 方法, 所以在非同步操作的完成和繫結處理方法之間不存在競爭。

new Promise((resolve,reject)=>{
	
}).then((data)=>{
},err=>{

}).catch(()=>{

})
複製程式碼

promise私有方法

Promise.all(iterable)

這個方法返回一個新的promise物件,該promise物件在iterable引數物件裡所有的promise物件都成功的時候才會觸發成功,一旦有任何一個iterable裡面的promise物件失敗則立即觸發該promise物件的失敗。這個新的promise物件在觸發成功狀態以後,會把一個包含iterable裡所有promise返回值的陣列作為成功回撥的返回值,順序跟iterable的順序保持一致;如果這個新的promise物件觸發了失敗狀態,它會把iterable裡第一個觸發失敗的promise物件的錯誤資訊作為它的失敗錯誤資訊。Promise.all方法常被用於處理多個promise物件的狀態集合。

Promise.race(iterable)

當iterable引數裡的任意一個子promise被成功或失敗後,父promise馬上也會用子promise的成功返回值或失敗詳情作為引數呼叫父promise繫結的相應控制程式碼,並返回該promise物件

Promise.reject(reason)

返回一個狀態為失敗的Promise物件,並將給定的失敗資訊傳遞給對應的處理方法

Promise.resolve(value)

返回一個狀態由給定value決定的Promise物件。

promise原型方法

Promise.prototype.catch(onRejected)

新增一個拒絕(rejection) 回撥到當前 promise, 返回一個新的promise。當這個回撥函式被呼叫,新 promise 將以它的返回值來resolve,否則如果當前promise 進入fulfilled狀態,則以當前promise的完成結果作為新promise的完成結果.

Promise.prototype.then(onFulfilled, onRejected)

新增解決(fulfillment)和拒絕(rejection)回撥到當前 promise, 返回一個新的 promise, 將以回撥的返回值來resolve。

Promise.prototype.finally(onFinally)

新增一個事件處理回撥於當前promise物件,並且在原promise物件解析完畢後,返回一個新的promise物件。回撥會在當前promise執行完畢後被呼叫,無論當前promise的狀態是完成(fulfilled)還是失敗(rejected)

jQuery中的promise規範

jquery用deferred實現了Promise規範,$.Deferred是個什麼玩意呢?還是老方法,列印出來看看,先有個直觀印象:

var def = $.Deferred();
console.log(def);
複製程式碼

promise設計模式

$.Deferred()返回一個物件,我們可以稱之為Deferred物件,上面掛著一些熟悉的方法如:done、fail、then等。jquery就是用這個Deferred物件來註冊非同步操作的回撥函式,修改並傳遞非同步操作的狀態。

Node.js的promise

安裝promise:

npm install promise --save
複製程式碼

然後你可以使用它將它載入到一個區域性變數中 require

var Promise = require('promise');
複製程式碼

"promise"庫還提供了一些與node.js互動的真正有用的擴充套件

var readFile = Promise.denodeify(require('fs').readFile);
function readJSON(filename, callback){
  return readFile(filename, 'utf8')
    .then(JSON.parse)
    .nodeify(callback);
}
複製程式碼

相關文章