JS手写一个简单的Promise实现

最近看b站, 跟着学了点手写promise

// 简单实现了 construct then  thenable 
//  promise 接受一个构造器  => 传入2个函数 resolve reject
//  promise 三种状态
//  promise 的then catch 方法
//  promise 的链式调用  
//  promise 的thenable 特性
//  promise 的异常捕获
//  promise 在进入任务队列中 以微任务的模式执行

const PENDING = "pending";
const FUILFIXED = "fuilfixed";
const REJECTED = "rejected";

class NPromise {
  status = PENDING
  result = undefined

  // 发布订阅模式
  onResolveList = [];
  onRejectList = [];

  // 构造器
  constructor(exection) {
    this.resolve = ((res) => {
      // 处理 resolve
      if (this.status === PENDING) {
        // 状态只会更改一次  不会进行二次更改
        this.result = res;
        this.status = FUILFIXED;

        // 处理订阅内容的函数
        this.onResolveList.forEach(fn => fn())
      }
    })

    this.reject = ((err) => {
      if (this.status === PENDING) {
        // 同理 进行状态的更改
        this.result = err;
        this.status = REJECTED

        // 处理发布的模式
        this.onRejectList.forEach(fn => fn());
      }
    })

    // 进行执行异常的捕获情况
    try {
      exection(this.resolve, this.reject);
    } catch (error) {
      throw new Error(error)
    }
  }

  handlePromise(res, newPromise, resolve, reject) {
    // 用来处理这个 让他返回一个新的promise对象
    if (res === newPromise) {
      // 防止重复调用
      throw new Error("can not refrences self ...")
    }


    // 处理 thenable 特性
    // 如果这个是promise的情况下
    if (res instanceof Promise) {

      if (this.status === PENDING) {
        res.then((val) => {
          this.handlePromise(val, undefined, resolve, reject)
        }, reject)
      } else if (this.status === FUILFIXED) {
        resolve(res)
      } else {
        reject(res)
      }

    } else if (
      // 处理具有 thenable特性的 方法
      // thenable  具有then 方法的 对象或者函数
      res !== null && res instanceof Object
    ) {

      try {
        const then = res.then;
        // 可能then调用回出错
        if (then instanceof Function) {
          // 如果 then 是一个方法的
          then.call(res, (val) => {
            this.handlePromise(val, undefined, resolve, reject)
          }, reject)

        } else {
          reject(res)
        }


      } catch (e) {
        reject(e)
      }

    }



  }
  // then 方法
  then(onResolve, onReject) {
    // 可能只有一个参数
    onResolve = onResolve instanceof Function ? onResolve : data => data;
    onReject = onReject instanceof Function ? onReject : err =>  {
      throw new Error(err)
    }


    // 实现promise的链式调用
    const _promise = new NPromise((resolve, reject) => {

      if (this.status === FUILFIXED) {
        try {
          setTimeout(() => {
            const res = onResolve(this.result)
            this.handlePromise(res, _promise, resolve, reject)
          })
        } catch (error) { 
          reject(error)
        }
      }

      if (this.status === REJECTED) {
        try {
          setTimeout(() => {
            const res = onReject(this.result)
            this.handlePromise(res, _promise, resolve, reject)
          })
        } catch (error) {
          reject(error)
        }
      }

      // 如果状态没有发生改变
      if (this.status === PENDING) {
        try {
          this.onResolveList.push(() => {
            const res = onResolve(this.result)
            this.handlePromise(res, _promise, resolve, reject)
          })

          this.onRejectList.push(() => {
            const res = onReject(this.result)
            this.handlePromise(res, _promise, resolve, reject)
          })
        } catch (error) {
          reject(error)
        }
      }

    })

    return _promise;
  }

  // catch 方法
  catch(onReject) {
    return this.then(undefined, onReject)
  }

  static resolve(res) {

  }
  static reject(err) {

  }

  all(promises){

  }
  
  race(promises){

  }
  
  // ...
}



const npromise = new NPromise((resolve, reject) => {
  resolve('hello world')
})

npromise.then(res => console.log(res))
console.log(123)

// 不能链式调用



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值