手写Promise

123 阅读2分钟

Provide inject

外层组件设置provide,其任意子组建通过inject注入。可传递方法或者数据

provide() {
    return {
      reload: this.reload
    }
  }
inject: ['reload'],

generator

const gen = function * (param) {
  console.log('param', param)
  const param2 = param + (yield 2)
  console.log('param2', param2)
  const param3 = param2 + (yield 3)
  console.log('param3', param3)
  return param3 + 4
}
const newGen = gen(11)
// param为11 param2为33 param3为66
console.log(newGen.next()) // {value: 2, done: false}
console.log(newGen.next(22)) // {value: 3, done: false}
console.log(newGen.next(33)) // {value: 70, done: true}
console.log(newGen.next(44)) // {value: undefined, done: true}

可以给没有迭代器的对象设置Symbol.iterator属性,然后对应对象就可以通过for of循环。Symbol.iterator属性对应的值是一个generator函数

const test = {}
test[Symbol.iterator] = gen
for (const key of test) {
  console.log('key', key)
}

实现一个简易Promise

class MyPromise {
  constructor(fn) {
    // promise所有状态
    this.state = {
      PENDING: 'PENDING', RESOLVED: 'RESOLVED', REJECTED: 'REJECTED'
    }
    // 用于回调的value,后面函数调用时候用的
    this.value = null
    // 回调函数列表,在执行then方法时候会将then传递的参数推入此数组,resolve方法执行之后执行
    this.resolvedCallBack = []
    this.rejectedCallBack = []
    // 当前状态
    this.status = this.state.PENDING
    // 缓存this
    MyPromise.that = this
    // 执行传入的fn方法
    fn && fn(MyPromise.resolve, MyPromise.reject)
  }
  // 静态方法
  static resolve(value) {
    // 从对象中获取this
    const that = MyPromise.that
    // 判断是MyPromise.resolve执行的还是new MyPromise执行的
    const isMy = that instanceof MyPromise
    // 如果是new MyPromise执行的
    if (isMy && that.status === that.state.PENDING) {
      that.value = value
      that.status = that.state.RESOLVED
      // 依次执行then中传入的回调
      that.resolvedCallBack.map(cb => {
        that.value = cb(that.value)
      })
    }
    if (!isMy) {
      // 如果是MyPromise.resolve执行的
      const obj = new MyPromise()
      // 返回一个已经resolve的MyPromise实例对象
      return Object.assign(obj, {
        status: obj.state.RESOLVED,
        value
      })
    }
  }
  // 静态方法
  static reject(value) {
    // 从对象中获取this
    const that = MyPromise.that
    // 判断是MyPromise.resolve执行的还是new MyPromise执行的
    const isMy = that instanceof MyPromise
    // 如果是new MyPromise执行的
    if (isMy && that.status === that.state.PENDING) {
      that.value = value
      that.status = that.state.REJECTED
      // 依次执行then中传入的回调
      that.rejectedCallBack.map(cb => {
        that.value = cb(that.value)
      })
    }
    if (!isMy) {
      // 如果是MyPromise.resolve执行的
      const obj = new MyPromise()
      // 返回一个已经resolve的MyPromise实例对象
      return Object.assign(obj, {
        status: obj.state.REJECTED,
        value
      })
    }
  }
  then(onFulFiled, onRejected) {
    onFulFiled = typeof onFulFiled === 'function' ? onFulFiled : c => c
    onRejected = typeof onRejected === 'function' ? onRejected : c => c
    if (this.status === this.state.PENDING) {
      // 如果是等待状态,就将then当中的方法放在数组中
      this.resolvedCallBack.push(onFulFiled)
      this.rejectedCallBack.push(onRejected)
    }
    if (this.status === this.state.RESOLVED) {
      // 如果是等待状态,就将then当中的方法放在数组中
      this.value = onFulFiled(this.value)
    }
    if (this.status === this.state.REJECTED) {
      // 如果是等待状态,就将then当中的方法放在数组中
      this.value = onFulFiled(this.value)
    }
    // 返回this,很关键,这样可以链式调用
    return this
  }
}

MyPromise.reject('haha').then((e) => {
  console.log(e)
  return e + 1
}).then(res => {
  console.log(res)
}, rej => console.log('rej', rej))
new MyPromise((resolve, reject) => {
  setTimeout(() => {
    if (Math.random() > 0.5) {
      console.log('resolve')
      resolve(1)
    } else {
      console.log('reject')
      reject(2)
    }
  }, 1000)
})
  .then(res1 => {
    console.log('res1', res1)
    return 'hahaha'
  }, res2 => console.log('res2', res2))
  .then(res2 => console.log(res2), res4 => console.log('res4', res4))