手写简化版Promise和手写Promis.all

22 阅读1分钟

手写简化版Promise

class Promise2 {
  #status = 'pending'
  constructor(fn){
    this.q = []
    const resolve = (data)=>{
      this.#status = 'fulfilled'
      const f1f2 = this.q.shift()
      if(!f1f2 || !f1f2[0]) return
      const x = f1f2[0].call(undefined, data)
      if(x instanceof Promise2) {
        x.then((data)=>{
          resolve(data)
        }, (reason)=>{
          reject(reason)
        })
      }else {
        resolve(x)
      }
    }
    const reject = (reason)=>{
      this.#status = 'rejected'
      const f1f2 = this.q.shift()
      if(!f1f2 || !f1f2[1]) return
      const x = f1f2[1].call(undefined, reason)
      if(x instanceof Promise2){
        x.then((data)=>{
          resolve(data)
        }, (reason)=>{
          reject(reason)
        })
      }else{
        resolve(x)
      }
    }
    fn.call(undefined, resolve, reject)
  }
  then(f1, f2){
    this.q.push([f1, f2])
  }
}

const p = new Promise2(function(resolve, reject){
  setTimeout(function(){
    reject('出错')
  },3000)
})

p.then( (data)=>{console.log(data)}, (r) => {console.error(r)} )

手写 Promise.all

要点:

  1. 知道要在 Promise 上写而不是在原型上写

  2. 知道 all 的参数(Promise 数组)和返回值(新 Promise 对象)

  3. 知道用数组来记录结果

  4. 知道只要有一个 reject 就整体 reject

Promise.prototype.myAll//错误的写法
Promise.myAll = function(list){
  const results = []
  let count = 0
  return new Promise((resolve,reject) =>{
    list.map((item, index)=> {
      item.then(result=>{
        results[index] = result
        count += 1
        if (count >= list.length) { resolve(results)}
      }, reason => reject(reason) )
    })
  })
}