// 构造函数
function Promise(executor){
this.promiseState = 'pending'// 状态
this.promiseResult = undefined// 结果
this.callbacks = []// 指定多个回调函数
const self = this
function resolve(data){
// 状态只能改变一次
if(self.promiseState!=='pending') return
// 修改状态
self.promiseState = 'fullfilled'//或者resolved
self.promiseResult = data
// 改变状态之后调用回调函数
self.callbacks.forEach(callback=>{
callback.onResolved(data)
})
}
function reject(data){
// 状态只能改变一次
if(self.promiseState!=='pending') return
// 修改状态
self.promiseState = 'rejected'
self.promiseResult = data
// 改变状态之后调用回调函数
self.callbacks.forEach(callback=>{
callback.onRejected(data)
})
}
// 同步调用执行器函数
try{
executor(resolve, reject)
}catch(e){
reject(e)
}
}
// 原型链添加then方法
Promise.prototype.then = function(onResolved, onRejected){
// catch穿透
if(typeof onRejected!=='function') onRejected = reason=>{throw reason}
if(typeof onResolved!=='function') onResolved = value=>value
const self = this
// 连续then回调
return new Promise((resolve, reject)=>{
function callback(func){
try{
let result = func(self.promiseResult)
if(result instanceof Promise){
result.then(value=>resolve(value), reason=>reject(reason))
}else{
resolve(result)
}
}catch(e){
reject(e)
}
}
switch(this.promiseState){
case 'fullfilled':
callback(onResolved, self.promiseResult)
break
case 'rejected':
callback(onRejected, self.promiseResult)
break
default:
this.callbacks.push(
{
onResolved: function(){
callback(onResolved, self.promiseResult)
},
onRejected: function(){
callback(onRejected, self.promiseResult)
}
}
)
break
}
})
}
// 添加catch方法
Promise.prototype.catch = function(onRejected){
this.then(undefined, onRejected)
}
// 添加Promise.resolve()方法
Promise.resolve = function(result){
return new Promise((resolve, reject)=>{
if(result instanceof Promise){
result.then(value=>resolve(value), reason=>reject(reason))
}else{
reject(result)
}
})
}
// 添加Promise.reject()方法
Promise.reject = function(reason){
return new Promise((_, reject)=>{
reject(reason)
})
}
// 添加Promise.all()方法
Promise.all = function(promises){
return new Promise((resolve, reject)=>{
let arr = []
for(let i=0;i<promises.length;i++){
promises[i].then(
value=>{
arr[i] = value
},
reason=>{
reject(reason)
}
)
}
resolve(arr)
})
}