以node EventEmitter为核心实现基础版promise
//利用node EventEmitter实现promise
var Promise = function(){
EventEmitter.call(this);//显式调用构造函数
}
util.inherits(Promise,EventEmitter);//利用node util工具函数inherits实现继承
Promise.prototype.then = function(fulfilledHandler, errorHandler, progressHandler){
if(typeof fulfilledHandler === 'function'){
this.once('success', fulfilledHandler);//利用once只调用一次
}
if(typeof errorHandler === 'function'){
this.once('error', errorHandler);
}
if(typeof progressHandler === 'function'){
this.on('progress',progressHandler);
}
return this;
}
var Deffered = function(){
this.state = 'unfulfilled';
this.promise = new Promise();
}
Deffered.prototype.resolve = function(obj){
this.state = 'fulfilled';
this.promise.emit('success',obj);
}
Deffered.prototype.reject = function(obj){
this.state = 'failed';
this.promise.emit('error',obj);
}
Deffered.prototype.progress = function(obj){
this.promise.emit('progress',obj);
}
//对一个简单的响应做封装
var promisify = function(res){
var deffered = new Deffered();
var result = '';
res.on('data', function(chunk){
result += chunk;
deffered.progress(chunk);
});
res.on('end', function(){
deffered.resolve(result);
});
res.on('error', function(err){
deffered.reject(err);
});
return deffered.promise;
}
//使用起来
promisifi(res).then(function(){},function(){},function(){});
不难看出,这里的deffered主要用于维护异步模型的状态,promise作用于外部,通过then()来添加自定义逻辑。
多异步协作应该如何实现呢?
//解决多异步协作的问题
Deffered.prototype.all = function(promises){
var count = promises.length;
var that = this;
var results = [];
promises.forEach(function(promise,i){
promise.then(function(data){
count--;
results[i] = data;
if(count === 0){
that.resolve(results);
}
},function(err){
that.reject(err);
});
});
return this.promise;
}
//调用多异步协作
var deffered = new Deffered();
deffered.all([promise1,promise2]).then(function(results){},function(err){})
后续思考::要想支持序列支持,即链式调用,主要需要两个步骤:
1、将所有回调逗存在队列中。
2、promise完成时,逐个执行回调,一旦检测到返回了新的promise对象,停止执行,然后将当前deffered对象的promise引用改编为新的promise对象,并将队列中余下的回调转交给新的promise。
具体实现可以参考《深入浅出nodejs》90页!~~