Promise介绍
Promise是ES语言标准里面提供的一种异步编程解决方案,promise相当于一个容器,promise容器的状态只有两种,完成状态,失败状态 ;容器的状态一旦改变就不可逆。
框架构成:promise是高级接口,事件模块events是低级模块并提供基础性支持
promise提案有很多种模型,CommonJS目前已经了Promises/A、Promises/B、Promises/D
下面以promiseA作说明:
- 一个promise只需提供一个then()方法,接受完成,错误状态的回调方法;当出现错误,或者状态完成时调用相应的方法。
- 可选的支持progress事件回调作为第三个方法。
- then方法只接受function对象,其余对象均会忽略。
- then方法继续返回promise对象,以便实现链式调用
then方法的定义:then(fulfilledHandler, errorHandler, progressHandler)
promiseA模型简单模仿:
var Promise = function () {
EventEmitter.call(this);
};
util.inherits(Promise, EventEmitter);
Promise.prototype.then = function (fulfilledHandler, errorHandler, progressHandler) {
if (typeof fulfilledHandler === 'function') {
//利用once方法只会执行一次,这就保证了promise的状态一旦定了就不会改变
this.once('success', fulfilledHandler);
}
if (typeof errorHandler === 'function') {
//利用once方法只会执行一次
this.once('error', errorHandler);
}
if (typeof progressHandler === 'function') {
、//progress可以多次触发,保证可以链式调用(可以一直触发progress事件)
this.on('progress', progressHandler);
}
return this;
};
//Deferred 延迟对象
var Deferred = function () {
this.state = 'unfulfilled';
this.promise = new Promise();
};
Deferred.prototype.resolve = function (obj) {
this.state = 'fulfilled';
this.promise.emit('success', obj);
};
Deferred.prototype.reject = function (err) {
this.state = 'failed';
this.promise.emit('error', err);
};
Deferred.prototype.progress = function (data) {
this.promise.emit('progress', data);
};
Promise封装实现异步编程
支持序列执行的promise封装
var fs=require('fs');
var Deferred=function () {
this.promise=new Promise();
};
Deferred.prototype.resovle=function (obj) {
var promise=this.promise;
var handler;
while (handler=promise.queue.shift()){
if (handler && handler.fulfilled){
var ret=handler.fulfilled(obj);
if (ret && ret.isPromise){
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;
}
}
}
};
//生成回调函数
Deferred.prototype.callback=function () {
var that=this;
return function (err,file) {
if (err) {
return that.reject(err);
}
that.resovle(file);
}
};
var Promise=function () {
//队列用来存储待执行的回调函数
this.queue=[];
this.isPromise=true;
};
Promise.prototype.then=function (fulfilledHandler,errorHandler,progressHandler) {
var handler={};
if (typeof fulfilledHandler ==="function"){
handler.fulfilled=fulfilledHandler;
}
if (typeof errorHandler ==="function"){
handler.error=errorHandler;
}
this.queue.push(handler);
return this;
};
var readFile1=function (file,encoding) {
var deferred=new Deferred();
fs.readFile(file,encoding,deferred.callback);
return deferred.promise;
};
var readFile2=function (file,encoding) {
var deferred=new Deferred();
fs.readFile(file,encoding,deferred.callback);
return deferred.promise;
};
readFile1('file1.txt','utf-8').then(function (file1) {
return readFile2(file1.trim(),'utf-8');
}).then(function (file2) {
console.log(file2);
});
//继续优化
var smoth=function (method) {
return function () {
var deffed=new Deferred();
var args=Array.prototype.slice.call(arguments,0);
args.push(deffed.callback());
method.apply(null,args);
return deffed.promise;
}
};
var readFile1_=function (file,encoding) {
var deffred=new Deferred();
fs.readFile(file,encoding,deffred.callback());
return deffred.promise;
};
var readFile2_=function (file,encoding) {
var deffred=new Deferred();
fs.readFile(file,encoding,deffred.callback());
return deffred.promise;
};
// var readFile=smoth(fs.readFile);
//要实现同样的效果,代码将会减少到
var readFile=smoth(fs.readFile);
readFile('file1.txt','utf-8').then(function (file1) {
return readFile(file1.trim(),'utf-8');
}).then(function (file2) {
console.log(file2);
});
**上面介绍的promise示范代码均为理解promiSee提案,在实际代码中请使用比较成熟的promise实现;when模块,或者q模块 可以使用npm install when/q**