class MyPromise{
static FULLFILLED = "成功"
static REJECTED = "拒绝"
static PENDING = "待定"
constructor(executor){
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
this.successCallbacks = []
this.failCallbacks = []
try{
executor(this.resolve,this.reject)
}catch(e){
this.reject(e.message)
}
}
resolve = (value)=>{
if(this.status !== MyPromise.PENDING) return
this.status = MyPromise.FULLFILLED
this.value = value
while(this.successCallbacks.length){
this.successCallbacks.shift()()
}
}
reject = (reason)=>{
if(this.status !== MyPromise.PENDING) return
this.status = MyPromise.REJECTED
this.reason = reason
while(this.failCallbacks.length){
this.failCallbacks.shift()()
}
}
then = (successCallback, failCallback)=>{
let p1 = new MyPromise((resolve,reject)=>{
const resolvePromise = (promise,value,resolve,reject)=> {
if(promise === p1){
throw new TypeError('chaining cycle detected for promise')
}
if(value instanceof MyPromise){
value.then(resolve,reject)
}else{
resolve(value)
}
}
if(this.status === MyPromise.FULLFILLED){
setTimeout(()=>{
try{
let value = successCallback(this.value)
resolvePromise(p1,value,resolve,reject)
}catch(e){
reject(e.message)
}
},0)
}else if(this.status === MyPromise.REJECTED){
setTimeout(()=>{
try{
let value = failCallback(this.reason)
resolvePromise(p1,value,resolve,reject)
}catch(e){
reject(e.message)
}
},0)
}else if(this.status === MyPromise.PENDING){
this.successCallbacks.push(()=>{
setTimeout(()=>{
try{
let value = successCallback(this.value)
resolvePromise(p1,value,resolve,reject)
}catch(e){
reject(e.message)
}
},0)
})
this.failCallbacks.push(()=>{
setTimeout(()=>{
try{
let value = failCallback(this.reason)
resolvePromise(p1,value,resolve,reject)
}catch(e){
reject(e.message)
}
},0)
})
}
})
return p1
}
finally = (cb)=>{
return this.then((value)=>{
return MyPromise.resolve(cb()).then(()=>value)
},reason=>{
return MyPromise.resolve(cb()).then(()=>{throw reason})
})
}
catch(failCallback){
return this.then(undefined,failCallback)
}
static resolve = (value)=>{
if(value instanceof MyPromise) return value
return new Promise(resolve=>resolve(value))
}
static all = (arr)=>{
let result = []
let index = 0
return new MyPromise((resolve,reject)=>{
const addData = (key,value)=>{
index++
result[key] = value
if(index = arr.length){
resolve(result)
}
}
for(let i = 0; i < arr.length; i++){
if(arr[i] instanceof MyPromise){
arr[i].then((res)=>{
addData(i,res)
},err => {
reject(err)
})
}else {
addData(i,arr[i])
}
}
})
}
}