ES6——Promi源码(原⽣javascript全部实现)ES6——Promi源码(原⽣javascript全部实现):
function MyPromi(func){
var lf =this;
lf.status ='pending';//进来时就先定义⼀个'pending'状态;等待调⽤时改变状态;
//完成异步操作:
好作文题目大全lf.ResolveCallBackList =[];//存储注册时成功的函数;
lf.RejectCallBackList =[];//存储失败时成功的函数;
//完成MyPromi的两个⽅法:
function resolve(value){//成功的⽅法;
if(lf.status ==='pending'){
lf.status ='Fulfilled';//成功回调触发'Fulfilled'状态;
lf.ResolveCallBackList.forEach(function(ele){//调⽤时可执⾏异步操作;;
ele();
});
}
};
function reject(reason){//失败的⽅法;
if(lf.status ==='pending'){
lf.status ='Rejected';//失败回调触发'Rejected'状态;
lf.RejectCallBackList.forEach(function(ele){//调⽤时可执⾏异步操作;
ele();
});
}
}
//同步执⾏时抛出错误后的兼容:
try{//当抛出错误后直接执⾏失败的回调函数;
func(resolve, reject);//创建MyPromi时就同步执⾏;
}catch(e){
reject(e)
}
};
//解决ruturn值的⽅法:
function ResolutionReturnProni(nextPromi, returnValue, res, rej){
//可以利⽤,之后的.then()注册的回调函数,都是注册在nextPromi⾝上的这⼀特点巧妙处理;
if(returnValue instanceof MyPromi){//返回值为Promi时:
returnValue.then(function(val){//直接让返回值链式调⽤.then()⽅法
res(val);//⽅法中成功⽅法直接执⾏成功回调;
},function(reason){
rej(reason);//失败⽅法直接执⾏失败回调;
})
}el{//返回值为普通值时
res(returnValue);//会执⾏成功的回调:
}
}
//完善.then()⽅法:
MyPromi.prototype.then=function(func1, func2){//原⽅法可插⼊成功和失败两个⽅法;
//处理空then():
if(!func1){//如果为空将参数原封不⽤返回;
互相帮助的作文
func1=function(val){
return val;
}
}
if(!func2){//如果为空将错误原封不动返回;
孩子不听话怎么办if(!func2){//如果为空将错误原封不动返回;
func2=function(reason){
throw new Error(reason);
}
}
var lf =this;
//实现原⽅法调⽤.then()⽅法是返回的是⼀个属性Promi对象;
var nextPromi =new MyPromi(function(res, rej){
//完成同步操作:
if(lf.status ==='Fulfilled'){
//.then()本⾝是异步操作:由于没有微任务权限,这⾥⽤tTimeout()使每⼀步为异步操作:
tTimeout(function(){
//完善数据捕获功能;(⽆论错误出现在成功还是失败中都会在失败的回调中找出)
try{
// var nextResolveValue = solveValue);
// //原⽅法返回⼀个普通值时会执⾏成功的回调:
// res(nextResolveValue);
var nextResolveValue =solveValue);
ResolutionReturnProni(nextPromi, nextResolveValue, res, rej);//由于异步执⾏,此处nextPromi可以直接传进去;
}catch(e){
rej(e);御史中丞
}
},0);
}
if(lf.status ==='Rejected'){
tTimeout(function(){
try{//完善数据捕获功能;
var nextRejectValue =jectReason);
// res(nextRejectValue); //原⽅法返回⼀个普通值时会执⾏成功的回调;
ResolutionReturnProni(nextPromi, nextRejectValue, res, rej);
}catch(e){
rej(e);
}
},0);
}
//完成异步操作:
if(lf.status ==='pending'){//如果状态为'pending'
lf.ResolveCallBackList.push(function(){//注册成功函数时放到成功回调数组中;
tTimeout(function(){
try{//完善数据捕获功能;
var nextResolveValue =solveValue);
// res(nextResolveValue); //原⽅法返回⼀个普通值时会执⾏成功的回调;
墨子悲丝
ResolutionReturnProni(nextPromi, nextResolveValue, res, rej);
}catch(e){
rej(e);
}
},0);
});
lf.RejectCallBackList.push(function(){//注册失败函数时放到成功回调数组中;
tTimeout(function(){
try{//完善数据捕获功能;
var nextRejectValue =jectReason);
// res(nextRejectValue); //原⽅法返回⼀个普通值时会执⾏成功的回调;
ResolutionReturnProni(nextPromi, nextRejectValue, res, rej);仓库管理员主要做什么
}catch(e){
rej(e);
}
},0);
});
}
});
//完成链式调⽤:
return nextPromi;//要知道:之后的.then()注册的回调函数,都是注册在nextPromi⾝上的;
};
};
//完善.race()⽅法:
MyPromi.race=function(promiArr){
return new MyPromi(function(resolve, reject){
promiArr.forEach(function(promi, index){
promi(resolve, reject);//哪个状态最先改变⼀定会先触发;
});
});
};
//完善.all()⽅法:
MyPromi.all=function(promiArr){
return new MyPromi(function(resolve, reject){
if(!Array.isArray(promiArr)){
return reject(new TypeError("argument must be anarray"));
}
var countNum =0;
var promiNum = promiArr.length;
var resolvedvalue =new Array(promiNum);
for(var i =0; i < promiNum; i++){
(function(i){
promiArr[i].then(function(value){//对每⼀个数组中的Promi对象进⾏单独.then(); countNum++;
resolvedvalue[i]= value;
if(countNum === promiNum){
return resolve(resolvedvalue)//全部成功时,输出所有的已存到数组中的结果;
}
},function(reason){
return reject(reason);//否则输出该最先被reject(reason) 的状态值;
});
})(i);
}
});
};
//测试MyPromi:
const oMP =new MyPromi((res, rej)=>{
// res('同步操作');
tTimeout(function(){
res('异步操作');
// rej('异步操作');
},500)
})
oMP.then((val)=>{
console.log(val +'-成功回调');
// return '成功';
// throw new Error('抛出错误');
return new MyPromi((res, rej)=>{
res('return Promi')
});
},(reason)=>{
console.log(reason +'-失败回调');
// return '失败';
throw new Error('抛出错误');
}).then((val)=>{
console.log(val +'-成功回调1');
},(reason)=>{
console.log(reason +'-失败回调2');
});
function text(num){
return new MyPromi((resolve, reject)=>{//return new Promi();
tTimeout(()=>{//进⾏⼀个异步操作;
tTimeout(()=>{//进⾏⼀个异步操作;
// resolve(num); //假设全部成功:执⾏结果为:[ 'a', 'b', 'c' ]
Math.random()*100>50?resolve(num):reject(num);//随机数⼤于50执⾏成功,否则执⾏失败;
},100)
});
}
const oMP1= MyPromi.all([text('a'),text('b'),text('c')])
.恐怖故事吧
then( val =>{
console.log('成功:'+ val);//全成功时才会触发成功回调;结果为:[ 'a', 'b', 'c' ] },(reason)=>{
console.log('失败:'+ reason);//有⼀个失败就返回最先被reject(num)的状态值;结果可能为 a || b || c;
});
炖牛排骨