简单版Promise

/**
 * 1. 绑定resolve reject 的this
 * 2. 状态不可变
 * 3. resolve reject 以第一次为准 
 * 4. throw 执行reject
 */
class MyPromise {
  /**
   * 
   * @param {*} executor 传进来的函数
   */
  constructor(executor) {
    this.initValue()
    this.initBind()//1
    //4
    try {
      executor(this.resolve, this.reject)
    } catch (error) {
      this.reject(error)
    }

  }
  initValue() {
    this.State = 'pending'
    this.result = null
    this.onFulfilledCallBacks = []
    this.onRejectedCallBacks = []
  }
  /**
   * 防止运行环境改变,resolve-this改变
   */
  initBind() {
    this.resolve = this.resolve.bind(this)
    this.reject = this.reject.bind(this)
  }
  /**
   * 要求pending=>fulfilled
   * 只改变一次
   * @param {*} value 成功是传进的值
   */
  resolve(value) {
    if (this.State !== 'pending') return //只改变一次 3,2
    this.State = 'fulfilled'
    this.result = value
    //通知then 回调
    while (this.onFulfilledCallBacks.length) {
      this.onFulfilledCallBacks.pop()()
    }
  }
  reject(reason) {
    if (this.State !== 'pending') return //只改变一次
    this.State = 'rejected'
    this.result = reason
    while (this.onRejectedCallBacks.length) {
      this.onRejectedCallBacks.pop()()
    }
  }
  /**
   * 1. 接受两个回调函数
   * 2. 定时器(异步执行)
   * 3. 链式调用
   * 4. then 可以被同一个promise调用多次
   * 5. 微任务
   * @param {fun} onFulfilled 成功回调
   * @param {fun} onRejected  失败回调
   */
  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val//简写参数判断
    onRejected = typeof onRejected === 'function' ? onRejected : reason => reason
    const thenPromise = new MyPromise((resolve, reject) => {

      /**
       * then 执行then 拿到他的值给下一个then使用//成功 或失败时候调用啊
       * @param {*} callback then 的回调函数
       */
      const resolvePromise = callback => {//绑定的是外部
        setTimeout(() => {
          //console.log(this)//this上一个Promise
          try {
            let callbackResult = callback(this.result)
            if (callbackResult instanceof MyPromise) {
              //执行结果就是MyPromise
              callbackResult.then(resolve, reject)// 等这个Promise自己决定成功还是失败
            } else {
              //直接就是成功的
              resolve(callbackResult)
            }
          } catch (error) {
            //回调执行失败
            reject(error)
          }
        })
      }
      if (this.State === 'fulfilled') {
        resolvePromise(onFulfilled)
      }
      if (this.State === 'rejected') {
        resolvePromise(onRejected)
      }
      if (this.State === 'pending') {
        //缓存回调 先进先出
        this.onFulfilledCallBacks.unshift(resolvePromise.bind(this, onFulfilled))
        this.onRejectedCallBacks.unshift(resolvePromise.bind(this, onRejected))
      }

    })
    return thenPromise//链式调用
  }

  /**
   *  相当于then(null,onReject)
   * @param {*} onRejected 
   * @returns 
   */
  catch(onRejected) {
    return this.then(null, onRejected);
  }
  /**
   * 指定不管 Promise 对象最后状态如何 
   * 回调函数不接受任何参数
   * 总是会返回原来的值
   * 返回的是一个
   */
  finnaly(callback) {
    return this.then(value => {
      MyPromise.resolve(callback()).then(() => value)
    }, reason => {
      MyPromise.reject(callback()).then(() => { throw reason })
    })
  }

  /**
   * 静态 resolve 把一个value 变成Promise
   * @param {any} 
   * 1. 参数是Promise 直接返回就是
   * 2. new Promise 包装一下
   */
  static resolve(value) {
    if (value && typeof value === 'object' && value instanceof MyPromise) {
      return value
    }
    return new MyPromise((resolve, reject) => {
      resolve(value)
    })
  }
  /**
   * 返回一个新的 Promise 实例,该实例的状态为rejected
   * @param {*} value 
   */
  static reject(value) {
    return new MyPromise((resolve, reject) => {
      reject(value)
    })
  }

  /**
   * 所有成功为成功,有错拒绝
   * @param {*} promiseArrs promise数组
   */
  static all(promiseArrs) {
    let res = []//promise数组执行结果
    let index = 0;
    return new MyPromise(resolve, reject => {
      if (promiseArrs.length) resolve([])
      promiseArrs.forEach((p, i) => {
        //先包一层 防止数组中有不是promise
        MyPromise.resolve(p).then(
          val => {
            index++;
            res[i] = val
            if (index == promiseArrs.length) {
              resolve(res)
            }
          },
          reason => {
            reject(reason)
          }
        )
      });
    })
  }

  /**
   * 返回第一个成功或者拒绝
   * @param {*} promiseArrs 
   * @returns 
   */
  static race(promiseArrs) {
    return new MyPromise(resolve, reject => {
      if (promiseArrs.length) resolve([])
      promiseArrs.forEach((p) => {
        //先包一层 防止数组中有不是promise
        MyPromise.resolve(p).then(
          val => {
            resolve(val)
          },
          reason => {
            reject(reason)
          }
        )
      });
    })
  }

  /**
   * 一组异步操作都结束了,不管每一个操作是成功还是失败,再进行下一步操作
   * @param {*} promiseArrs 
   */
  static AllSettled(promiseArrs){
    let res = []//promise数组执行结果
    let index = 0;
    return new MyPromise(resolve, reject => {
      if (promiseArrs.length) resolve([])

      const fn = (status,val,i)=>{
        res[i] = {
          status,val
        }
        index++;
        if(index==promiseArrs.length){
          resolve(res)
        }
      }

      promiseArrs.forEach((p, i) => {
        //先包一层 防止数组中有不是promise
        MyPromise.resolve(p).then(
          val => {
            fn("fulfilled",val,i)
          },reason=>{
            fn("rejected",reason,i)
          }
        )
      });
    })
  }

  /**
   * all 相反 有成功就成功
   * @param {*} promiseArrs 
   */
  static any(promiseArrs){
    let index = 0;
    let res = []
    return new MyPromise((resolve,reject)=>{
      if (promiseArrs.length) resolve([])
      promiseArrs.forEach((p,i)=>{
        MyPromise.resolve(p).then(
          val=>{
            resolve(val)
          },reason=>{
            index++;
            res[i] = reason
            if(index==promiseArrs.length)
            {
              reject(res)
            }
          }
        )
      })
    })
  }
}

总结

尽量和Promise+规范靠近,但是还是不足
比如 Promise 是一个微任务,但是这里用计时器
Promise.resolve 没对thenable对象处理等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值