Promise原理淺析
Promise介紹
介紹
Promise 對象用于延遲(deferred) 計算和異步(asynchronous ) 計算.。一個Promise對象代表著一個還未完成,但預期將來會完成的操作。 Promise 對象是一個返回值的代理,這個返回值在promise對象創建時未必已知。它允許你為異步操作的成功或失敗指定處理方法。 這使得異步方法可以像同步方法那樣返回值:異步方法會返回一個包含了原返回值的 promise 對象來替代原返回值。
引自 MDN
</div>它解決什么問題
一個簡單的示例 執行一個動畫A,執行完之后再去執行另一個動畫B
setTimeout(function(){ //A動畫 console.log('A'); setTimeout(function() { //B動畫 console.log('B'); },300) },300);
這里只有兩個動畫,如果有更多呢,就會看到一堆函數縮進
一種寫法
瀏覽器實現方式 可以在支持Promise的版本上運行
var p = new Promise(function(resolve, reject){ setTimeout(function(){ //A動畫 console.log('A'); resolve(); },300); });p.then(function(){ setTimeout(function() { //B動畫 console.log('B'); },300); });</pre>
另一種寫法(jQuery版本)
jQuery版本的實現
var deferred = $.Deferred(); setTimeout(function(){ //A動畫 console.log('A'); deferred.resolve(); },300);deferred.done(function() { setTimeout(function() { //B動畫 console.log('B'); },300) });</pre>
好像從代碼上來看,是多了幾行的樣子,但是能用這種串行的方式來寫,感覺一定很爽吧
Promise中的概念
Promise中有幾個狀態:
- pending: 初始狀態, 非 fulfilled 或 rejected.
- fulfilled: 成功的操作.
- rejected: 失敗的操作.
這里從pending狀態可以切換到fulfill狀態(jQuery中是resolve狀態),也可以從pengding切換到reject狀態,這個狀態切換不可逆,且fulfilled和reject兩個狀態之間是不能互相切換的。
一個簡單版本的實現
/** * simple promise * @param {[type]} fun [description] */ function PromiseB(fun) { this.succArg = undefined; this.failArg = undefined; this.succCbs = []; this.failCbs = []; this._status = this.STATUS.PENDING; this._execFun(fun); } PromiseB.prototype.STATUS = { PENDING: 1, //掛起狀態 RESOLVE: 2, //完成狀態 REJECT: 3 //拒絕狀態 }; PromiseB.prototype._isFunction = function(f) { return Object.prototype.toString.call(f) === '[object Function]'; }; PromiseB.prototype._exec = function(callback, arg) { var newcallback; if (this._isFunction(callback)) { if (callback instanceof PromiseB) { callback.resolve(arg); } else { newcallback = new PromiseB(callback); newcallback.resolve(arg); } } }; PromiseB.prototype._execFun = function(fun) { var that = this; if (this._isFunction(fun)) { fun(function() { that.succArg = Array.prototype.slice.apply(arguments); that._status = that.STATUS.RESOLVE; that.resolve.apply(that, arguments); }, function() { that.failArg = Array.prototype.slice.apply(arguments); that._status = that.STATUS.REJECT; that.reject.apply(that, arguments); }); } else { this.resolve(fun); } }; PromiseB.prototype.resolve = function() { var arg = arguments, ret, callback = this.succCbs.shift(); if (this._status === this.STATUS.RESOLVE && callback) { ret = callback.apply(callback, arg); if (!(ret instanceof PromiseB)) { var _ret = ret; ret = new PromiseB(function(resolve) { setTimeout(function() { resolve(_ret); }); }); ret.succCbs = this.succCbs.slice(); } // this._exec(callback.apply(callback, arg), arg); } }; PromiseB.prototype.reject = function() { var arg = arguments, ret, callback = this.failCbs.shift(); if (this._status === this.STATUS.REJECT && callback) { ret = callback.apply(callback, arg); if (!(ret instanceof PromiseB)) { var _ret = ret; ret = new PromiseB(function(resolve) { setTimeout(function() { resolve(_ret); }, 200); }); ret.failCbs = this.failCbs.slice(); } } }; PromiseB.prototype.then = function(s, f) { this.done(s); this.fail(f); return this; }; PromiseB.prototype.done = function(fun) { if (this._isFunction(fun)) { if (this._status === this.STATUS.RESOLVE) { fun.apply(fun, this.succArg); } else { this.succCbs.push(fun); } } return this; }; PromiseB.prototype.fail = function(fun) { if (this._isFunction(fun)) { if (this._status === this.STATUS.REJECT) { fun.apply(fun, this.failArg); } else { this.failCbs.push(fun); } } return this; }; PromiseB.prototype.always = function(fun) { this.done(fun); this.fail(fun); return this; };
總結
- promise會讓代碼變得更容易維護,像寫同步代碼一樣寫異步代碼
- 了解promise的原理,寫個簡單的實現版本就好了
- promise的實現方案有很多,可以看 這里
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!