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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!