利用nodejs的event模塊,可以實現(xiàn)一個最簡單的Promise/Deferred框架:
Promise
// Promise 繼承自EventEmitter
var Promise = function () {
EventEmitter.call(this);
};
util.inherits(Promise,EventEmitter);
// then方法,綁定成功、失敗、進度事件
Promise.prototype.then = function (fulfilledHandler, errorHandler, progressHandler) {
if (typeof fulfilledHandler === 'function') {
this.once('success',fulfilledHandler)
}
if (typeof errorHandler === 'function') {
this.once('error', errorHandler);
}
return this;
};
Deferred
var Deferred = function () {
this.state = 'unfulfilled';
this.promise = new Promise();
};
// 觸發(fā)成功事件
Deferred.prototype.resolve = function (obj) {
this.state = 'fulfilled';
this.promise.emit('success',obj);
};
// 觸發(fā)失敗事件
Deferred.prototype.reject = function (err) {
this.state = 'failed';
this.promise.emit('error',err);
};
使用方法
function test() {
var defer = new Deferred();
setTimeout(function(){
defer.resolve('test')
},0);
return defer.promise;
}
test()
.then(function(msg){
console.log(msg); // test
})
實現(xiàn)鏈式調用
- Promise
var Promise = function () {
EventEmitter.call(this);
// 隊列用于存儲待執(zhí)行的回調函數(shù)
this.queue = [];
this.isPromise = true;
};
util.inherits(Promise,EventEmitter);
Promise.prototype.then = function (fulfilledHandler, errorHandler, progressHandler) {
var handler = {};
if (typeof fulfilledHandler === 'function') {
handler.fulfilled = fulfilledHandler;
}
if (typeof errorHandler === 'function') {
handler.error = errorHandler;
}
// 將then中傳入的函數(shù)都添加到promise的隊列中
this.queue.push(handler);
// then函數(shù)返回自身
return this;
};
- Deferred
var Deferred = function () {
this.state = 'unfulfilled';
this.promise = new Promise();
};
Deferred.prototype.resolve = function (obj) {
var promise = this.promise;
var handler;
while ((handler = promise.queue.shift())) {
if (handler && handler.fulfilled) {
// 正常情況下,fulfilled函數(shù)會繼續(xù)返回一個promise
var ret = handler.fulfilled(obj);
if (ret && ret.isPromise) {
// 將當前Defferred對象的promise引用改為新的Promise對象,將隊列中余下的回調轉交給它
ret.queue = promise.queue;
this.promise = ret;
return;
}
}
}
};
Deferred.prototype.reject = function (err) {
var promise = this.promise;
var handler;
while ((handler = promise.queue.shift())) {
if (handler && handler.error) {
var ret = handler.error(err);
if (ret && ret.isPromise) {
ret.queue = promise.queue;
this.promise = ret;
return;
}
}
}
};
- 使用
function test() {
var defer = new Deferred();
setTimeout(function(){
defer.resolve('test1')
},0);
return defer.promise;
}
test()
.then(function(msg){
console.log(msg);
var defer = new Deferred();
setTimeout(function(){
defer.resolve('test2')
})
return defer.promise;
})
.then(function(msg){
console.log(msg)
})
歡迎光臨我的博客:http://www.paradeto.com