Promise是個什麼玩意,你們都知道,度娘告訴我,以同步方式書寫異步,解決回調地獄。。。git
早聞Promise的大名,簡單介紹,根據狀態改變來執行相應處理函數。
Promise的狀態極其簡單,只有 "pending", "resolved", "rejected"三種狀態
而後就是如何實現的問題,最關鍵的固然是監聽到狀態的更新,而後才能作出迴應,那麼如何知道狀態變了呢?
最初單純的我開了一個腦洞,有如下想法:github
嗚嗚嗚,有時候總會犯傻不是,上面第一種維護一個定時器,效率低下;第二種把狀態變得很麻煩和複雜;
其實不少事情之因此複雜,是由於咱們想的太多。
Promise根本沒那麼複雜,就三個狀態,搞毛線定時器,狀態跟蹤。
利用觀察者模式,只須要經過特定書寫方式註冊對應狀態的事件處理函數,而後更新狀態,調用註冊過的處理函數便可。這個特定方式就是 then ,done ,fail, always...等方法;更新狀態觸發時機就是resolve, reject方法。app
理論分析:異步
代碼以下:函數
/** * [3種狀態] * @type {String} */ var PENDING = "pending"; var RESOLVED = "resolved"; var REJECTED = "rejected"; /** * [Promise類實現] * 構造函數傳入一個fn,有兩個參數,resolve:成功回調; reject:失敗回調; * state: 狀態存儲 * doneList: 成功處理函數列表 * failList: 失敗處理函數列表 * done: 註冊成功處理函數 * fail: 註冊失敗處理函數 * then: 同時註冊成功和失敗處理函數 * always: 一個處理註冊到成功和失敗,都會調用 * resolve: 更新state爲:RESOLVED,而且執行成功處理隊列 * reject: 更新state爲:REJECTED,而且執行失敗處理隊列 */ var Promise = (function (){ function Promise(fn){ this.state = PENDING; this.doneList = []; this.failList = []; this.fn = fn; this.fn(this.resolve.bind(this), this.reject.bind(this)) } var p = { done: function (cb){ if(typeof cb == "function") this.doneList.push(cb) return this; }, fail: function(cb){ if(typeof cb == "function") this.failList.push(cb); return this; }, then: function(success, fail){ this.done(success || noop).fail(fail || noop) return this; }, always: function(cb){ this.done(cb).fail(cb) return this; }, resolve: function(){ this.state = RESOLVED; var lists = this.doneList; for(var i = 0, len = lists.length; i<len; i++){ lists[0].apply(this, arguments); lists.shift(); } return this; }, reject: function(){ this.state = REJECTED; var lists = this.failList; for(var i = 0, len = lists.length; i<len; i++){ lists[0].apply(this, arguments); lists.shift(); } return this; } } for(var k in p){ Promise.prototype[k] = p[k] } return Promise; })(); function noop(){}
使用方式,請到https://github.com/donglegend/MyPromise下載使用oop