//promise三种状态(运行中,执行成功,执行失败)
const PENDING='pending'
const RESOLVE='fulfilled'
const REJECTED='rejected'
function MyPromise(executor){
this.data=undefined
this.Fullcallback=[]//存放成功的回调
this.Failedcallback=[]//存放失败的回调
this.status=PENDING
function resolve(data){
if(this.status===PENDING){
this.status=RESOLVE
this.data=data;
this.Fullcallback.forEach(element => {
setTimeout(()=>{element(this.data)},0)
});
}
}
function reject(err){
if(this.status===PENDING){
this.status=REJECTED
this.data=err
this.Failedcallback.forEach(element=>{
setTimeout(()=>{element(this.data)},0)
})
}
}
try{executor(resolve,reject)}catch(e){
reject(e)
}
}
MyPromise.prototype.then=function(onFulfilled,onRejected){
onFulfilled=typeof onFulfilled==='function'?onFulfilled:val=>val
onRejected=typeof onRejected==='function'?onRejected:err=>{throw err};
var self=this;
if(self.status===PENDING){
return promise2=new MyPromise((resolve,reject)=>{
self.Fullcallback.push((value)=>{
try{
let x=onFulfilled(value)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
})
self.Failedcallback.push((value)=>{
try{
let x=onRejected(value)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
})
})
}
if(self.status===RESOLVE){
return promise2=new MyPromise((resolve,reject)=>{
setTimeout(()=>{
try{
let x=onFulfilled(self.data)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
}
if(self.status===REJECTED){
return promise2=new MyPromise((resolve,reject)=>{
setTimeout(()=>{
try{
let x=onRejected(self.data)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
})
})
}
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2===x){throw Error()}
let called=false;
if(x!==null&&typeof x=='function'||typeof x=='object'){
try{
let then=x.then
if(typeof then==='function'){
try{
then.call(x,y=>{
if(called)return
called=true
resolvePromise(promise2,y,resolve,reject)
})}catch(e){
if(called)return;
called=true;
reject(e)
}
}else{
resolve(x)
}
}catch(e){
if(called)return
called=true;
reject(e)
}
}else{
resolve(x)
}
}
MyPromise.resolve=function(data){
return new MyPromise(reslove=>{reslove(data)})
}
MyPromise.reject=function(data){
return new MyPromise((resolve,reject)=>{reject(data)})
}