1.Promise理解
- Promise本质是一个状态机,每个Promise只能是三种状态中的一种:pending,fulfilled,rejected
状态转变只能是 pending -> fulfilled 或者 pending -> rejected,状态转变不可逆
- then方法可以被同一个Promise链式调用多次
- then方法必须返回一个新的Promise
2.Promise实现代码
function Promise(fn){
//安全的构造函数
if(!(this instanceof Promise)){
return new Promise(fn);
}
var self=this;
//先执行函数本身,然后调用resolve的时候运行存储在doneList中的回调函数
this.doneList=[]; //成功回调函数队列
this.failList=[]; //失败回调函数队列
this.status='PENDING'; //状态
this.value=null;
this.error=null;
//Promise改变状态,执行其成功回调函数队列
function resolve(value){
setTimeout(function(){
self.status='FULFILLED';
self.value=value;
self.doneList.forEach(function(done){
self.value=done(self.value); //将计算结果依次传递下去
});
});
}
//Promise改变状态,执行其失败回调函数队列
function reject(error){
setTimeout(function(){
self.status='REJECTED';
self.error=error;
self.failList.forEach(function(fail){
self.error=fail(self.error); //将错误处理结果依次传递下去
});
});
}
fn(resolve,reject);
}
Promise.prototype={
constructor: Promise,
then: function(done,fail){
var self=this;
return new Promise(function(resolve,reject){
//对then中的回调函数进行包装,并执行resolve
function handle(value){
//成功和错误处理函数必须是函数才调用,否则直接返回上一个值
var res=typeof done==='function' && done(value) || value;
//如果返回一个Promise对象,则调用其then方法,等待获取其中的返回值
if(res && typeof res['then']==='function'){
res.then(function(value){
//调用resolve时,会执行其成功回调函数列表
resolve(value);
});
} else {
resolve(res);
}
}
function errback(error){
error=typeof fail==='function' && fail(error) || error;
reject(error);
}
if(self.status==='PENDING'){
self.doneList.push(handle);
self.failList.push(errback);
} else if(self.status==='FULFILLED'){
//已完成后调用then则直接传入计算结果
handle(self.value);
} else if(self.status==='REJECTED'){
//已完成后调用则直接传入异常
errback(self.error);
}
});
},
resolve: function(arg){
return new Promise(function(resolve,reject){
resolve(arg);
});
},
reject: function(arg){
return new Promise(function(resolve,reject){
reject(arg);
});
},
catch: function(fail){
return this.then(undefined,fail);
}
}
//用Promise.then封装串行异步函数
var res=new Promise(function(resolve){
console.log(1);
resolve(2);
}).then(function(num){
return new Promise(function(resolve,reject){
setTimeout(function(){
console.log(num);
resolve(num);
},1000);
});
}).then(function(num){
return new Promise(function(resolve,reject){
setTimeout(function(){
console.log(num);
resolve(num);
},1000);
});
});
//状态已改变,则直接传入结果或错误
res.then(function(num){
console.log(num);
});
console.log(3);