手写Promise(all,race,allSettled,any)

手写Promise

function myPromise(excutor){
  let self = this
  self.status = 'pending'
  self.value = null
  self.reason = null
  self.onfulfilledCallback = []
  self.onrejectedCallback = []

  function resolve(value){
    if(self.status == 'pending'){
      self.status = 'onfulfilled'
      self.value = value
      self.onfulfilledCallback.forEach(item=>{
        item(value)
      })
    }
  }
  function reject(reason){
    if(self.status == 'pending'){
      self.status = 'onrejected'
      self.reason = reason
      self.onrejectedCallback.forEach(item=>{
        item(reason)
      })
    }
  }
  try{
    excutor(resolve,reject)
  }catch(err){
    reject(err)
  }
}
myPromise.prototype.then = function(onFulfilled,onRejected){
  let self = this
  onFulfilled = typeof onFulfilled == 'function'?onFulfilled:function(data){resolve(data)}
  onRejected = typeof onRejected == 'function'?onRejected:function(err){throw err}
  if(self.status == 'onfulfilled'){
    return new myPromise((resolve,reject)=>{
      try{
        let x = onFulfilled(self.value)
        x instanceof myPromise?x.then(resolve,reject):resolve(x)
      }catch(err){
        reject(err)
      }
    })
  }
  if(self.status == 'onrejected'){
    return new myPromise((resolve,reject)=>{
      try{
        let x = onRejected(self.reason)
        x instanceof myPromise?x.then(resolve,reject):resolve(x)
      }catch(err){
        reject(err)
      }
    })
  }
  if(self.status == 'pending'){
    return new myPromise((resolve,reject)=>{
      self.onfulfilledCallback.push(function(){
        let x = onFulfilled(self.value)
        x instanceof myPromise?x.then(resolve,reject):resolve(x)
      })
      self.onrejectedCallback.push(function(){
        let x = onRejected(self.reason)
        x instanceof myPromise?x.then(resolve,reject):resolve(x)
      })
    })
  }
}
myPromise.prototype.catch = function (fn){
  return this.then(null,fn)
}
myPromise.prototype.finally = function (resolvefn,rejectfn){
  return this.then(resolvefn,rejectfn)
}

let p = new myPromise((resolve,reject)=>{
  resolve('p')
}) 

p.then(data=>{
  console.log('resolve',data) // resolve p
}).catch(err=>{
  console.log('reject',err)
})

手写Promise.all()

const p = Promise.all([p1, p2, p3]);

Promise.all()方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。

p的状态由p1、p2、p3决定,分成两种情况。

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

myPromise.myAll = function(promiseArr){
  return new myPromise((resolve,reject)=>{
    let count = 0
    let arr = []
    for(var i=0;i<promiseArr.length;i++){
      promiseArr[i].then(v=>{
        count ++
        arr[i] = v
        if(count == promiseArr.length){
          resolve(arr)
        }
      },err=>{
        reject(err)
      })
    }
  })
}

let p = new myPromise((resolve,reject)=>{
  resolve('p')
}) 
let p1 = new myPromise((resolve,reject)=>{
  reject('p1')
}) 
let p2 = new myPromise((resolve,reject)=>{
  reject('p2')
}) 


myPromise.myAll([p,p1,p2]).then(value=>{
  console.log('all--resolve',value)
}).catch(err=>{
  console.log('all--reject',err) //all--reject p1
})

手写Promise.race()

const p = Promise.race([p1, p2, p3]);

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

 myPromise.myRace = function(promiseArr){
  return new myPromise((resolve,reject)=>{
    for(var i =0;i<promiseArr.length;i++){
      promiseArr[i].then(value=>{
        resolve(value)
      },err=>{
        reject(err)
      })
    }
  })
}

let p = new myPromise((resolve,reject)=>{
  resolve('p')
}) 
let p1 = new myPromise((resolve,reject)=>{
  reject('p1')
}) 
let p2 = new myPromise((resolve,reject)=>{
  reject('p2')
}) 

myPromise.myRace([p2,p,p1]).then(value=>{
  console.log('race--resolve',value) 
}).catch(err=>{
  console.log('race--reject',err) //race--reject p2
})

手写Promise.allSettled()

const p = Promise.allSettled([p1, p2, p3]);

Promise.allSettled()方法接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled还是rejected),返回的 Promise 对象才会发生状态变更。

myPromise.myAllSettled = function(promiseArr){
  return new myPromise((resolve,reject)=>{
    let count = 0
    let arr = []
    for(var i=0;i<promiseArr.length;i++){
      promiseArr[i].finally(v=>{
        count ++
        arr[i] = {status:'fulfilled',value:v}
        if(count == promiseArr.length){
          resolve(arr)
        }
      },err=>{
        count ++
        arr[i] = {status:'rejected',reason:err}
        if(count == promiseArr.length){
          resolve(arr)
        }
      }
      )
    }
  })
}

let p = new myPromise((resolve,reject)=>{
  resolve('p')
}) 
let p1 = new myPromise((resolve,reject)=>{
  reject('p1')
}) 
let p2 = new myPromise((resolve,reject)=>{
  reject('p2')
})

myPromise.myAllSettled([p,p1,p2]).then(value=>{
  console.log('allSettled--resolve',value)
}).catch(err=>{
  console.log('allSettled--reject',err)
}) 
//allSettled--resolve 
(3) [{…}, {…}, {…}]
0: {status: 'fulfilled', value: 'p'}
1: {status: 'rejected', reason: 'p1'}
2: {status: 'rejected', reason: 'p2'}
length: 3[[Prototype]]: Array(0)

手写Promise.any()

const p = Promise.any([p1, p2, p3]);

只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态

myPromise.myAny = function(promiseArr){
  return new myPromise((resolve,reject)=>{
    let count = 0
    let arr = []
    for(var i=0;i<promiseArr.length;i++){
      promiseArr[i].then(v=>{
        resolve(v)
      },err=>{
        count ++
        arr[i] = err
        if(count == promiseArr.length){
          reject(arr)
        }
      })
    }
  })
}

let p = new myPromise((resolve,reject)=>{
  resolve('p')
}) 
let p1 = new myPromise((resolve,reject)=>{
  reject('p1')
}) 
let p2 = new myPromise((resolve,reject)=>{
  reject('p2')
}) 

myPromise.myAny([p,p1,p2]).then(value=>{
  console.log('any--resolve',value) //any--resolve p
}).catch(err=>{
  console.log('any--reject',err)
})
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值