手撸Promise--下

12 手撸promise

如何实现Promise异步调用?如何实现Promise链式调用,其实真理就在其中,我简单按照我的网上理解简单写了一下…

class testPromise{
  #status //定义私有变量
  #itSuccess='FULFILLED'
  #itError = 'REJECTED' 
  #itWait = 'PENDING' //定义初始化变量
  #theValue = null
  constructor(executor){
    if(typeof executor !=='function'  ){
      throw new Error("testPromise must accept a function as a param")
    }
    // 首先的有这个状态
    this.#status = this.#itWait
    const resolve = value=>{
      //进来后状态改变
      if(this.#status!==this.#itWait) return
        this.#status = this.#itSuccess
        this.#theValue = value
    }
   const reject = value=>{
     if(this.#status!==this.#itWait) return
     this.#itWait = this.#itError
     this.#theValue = value
   } 
    executor(resolve,reject)
  }
  then(onFulfilled,onReject){
    if(this.#status==this.#itSuccess){
      onFulfilled(this.#theValue)
    }
    if(this.#status==this.#itError){
      onReject(this.#theValue)
    }
  }
  catch(onRejected){
    //直接调用上面的
    this.then(null,onRejected)
  }
}
let one = new testPromise((resolve,reject)=>{
   resolve("resolve")
   console.log("加载了resolve")
   reject("reject")
})
one.then(res=>{
  console.log(res)
},err=>{
  console.log(err)
})
console.log("按道理应该先执行我")  //但是没有
//现在就是完成了简单了promise

在这里插入图片描述

接下来就是解决上面的异步,想到异步我们就想到什么,
  • setTimeout

相当于是一个异步任务,.then执行是等resolve或者reject之后才执行,什么情况下能控制他们在以后执行,,任务队列!!!

就是我不管你什么时候resolve,或者reject ,.then的时候我先把这个执行函数放到任务队列里面 ,等 reject,和resolve时再调用

class testPromise{
  #status
  #itSuccess='FULFILLED'
  #itError = 'REJECTED'
  #itWait = 'PENDING'
  #theValue = null
  //2.0解决异步加入
  #onFulfilledCalArr = []
  #onRejectedCalArr = []
  constructor(executor){
    if(typeof executor !=='function'  ){
      throw new Error("testPromise must accept a function as a param")
    }

    // 首先的有这个状态
    this.#status = this.#itWait
    const resolve = value=>{
      //进来后状态改变
      if(this.#status!==this.#itWait) return
        this.#status = this.#itSuccess
        this.#theValue = value
        //2.0加入
        this.#onFulfilledCalArr.forEach(fn=>fn())
    }
   const reject = value=>{
     if(this.#status!==this.#itWait) return
     this.#itWait = this.#itError
     this.#theValue = value
     //2.0加入
     this.#onRejectedCalArr.forEach(fn=>fn())
   } 
    executor(resolve,reject)
  }
  then(onFulfilled,onReject){
    //2.0加入
    setTimeout(()=>{
      //成功态
      if(this.#status==this.#itSuccess){
          onFulfilled(this.#theValue)
      }
      //失败态
    else  if(this.#status==this.#itError){
         onFulfilled(this.#theValue)
      }
      //等待态 因为这里可能在promise里面可能还有定时的时候
    else{
      this.#onFulfilledCalArr.push(()=>onFulfilled(this.#theValue)) //加入队列里面
      this.#onRejectedCalArr.push(()=>onReject(this.#theValue))
    }
    },0)
  }
  catch(onRejected){
    //直接调用上面的
    this.then(null,onRejected)
  }
}
let one = new testPromise((resolve,reject)=>{
   console.log("第一个执行")
   setTimeout(()=>{
    resolve("时间延迟1s进行resolve我应该是最后一个执行")
    reject("在resolve后面 不会执行的")
   })
})
one.then(res=>{
  
  console.log(res)
  console.log("里面res微任务后执行")
},err=>{
  console.log(err)
  console.log("reject不会执行的")
})
console.log("外面宏任务先执行") 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TX1zBaYM-1667827809849)(记录.assets/image-20221107205128450.png)]

这样就完成了任务异步执行,所以解决关键点就是在任务数组里面插入函数,需要执行时才执行

最后一个是什么?是不是链式执行

链式?这里自己链式下去,也就是说,自己还能接着调用自己,也就是说 then里面返回的也是promise咯,那就在异步的情况上加呗

class testPromise {
  #status
  #itSuccess = 'FULFILLED'
  #itError = 'REJECTED'
  #itWait = 'PENDING'
  #theValue = null
  //2.0解决异步加入
  #onFulfilledCalArr = []
  #onRejectedCalArr = []
  constructor(executor) {
    if (typeof executor !== 'function') {
      throw new Error("testPromise must accept a function as a param")
    }

    // 首先的有这个状态
    this.#status = this.#itWait
    const resolve = value => {
      //进来后状态改变
      if (this.#status !== this.#itWait) return
      this.#status = this.#itSuccess
      this.#theValue = value
      //2.0加入
      this.#onFulfilledCalArr.forEach(fn => fn())
    }
    const reject = value => {
      if (this.#status !== this.#itWait) return
      this.#itWait = this.#itError
      this.#theValue = value
      //2.0加入
      this.#onRejectedCalArr.forEach(fn => fn())
    }
    executor(resolve, reject)
  }
  then(onFulfilled, onReject) {
    //3.0 链式加入
    return new testPromise((resolve, reject) => {
      //实行异步
      setTimeout(() => {
        //成功态
        if (this.#status == this.#itSuccess) {
          let returnVal = onFulfilled(this.#theValue) //成功态去看返回的是什么值 
          /**   new Promise(resolve=>{
               resolve(1)
             }).then(res=>{
               return new Promise(resolve=>{
               })
             })
             */
          if (returnVal instanceof testPromise) { //如上情形
            returnVal.then(resolve, reject) //此时就得提前调用then 把这些函数存进任务队列
          } else {
            //普通值直接就去执行了
            resolve(returnVal)
          }
        }
        //失败态
        else if (this.#status == this.#itError) {
          let returnVal = onReject(this.#theValue)
          if (returnVal instanceof testPromise) {
            returnVal.then(resolve, reject) //如上
          } else {
            reject(returnVal)
          }
        }
        else {
          //这个就是直接把上面去两种情况加入到任务队列里面去
          //成功函数
          let resolveFn = () => {
            let returnVal = onFulfilled(this.#theValue) //成功态去看返回的是什么值 
            if (returnVal instanceof testPromise) { //如上情形
              returnVal.then(resolve, reject) //此时就得提前调用then 把这些函数存进任务队列
            } else {
              //普通值直接就去执行了
              resolve(returnVal)
            }
          }
          //失败函数
          let rejectFn = () => {
            let returnVal = onReject(this.#theValue)
            if (returnVal instanceof testPromise) {
              returnVal.then(resolve, reject) //如上
            } else {
              reject(returnVal)
            }
          }
          this.#onFulfilledCalArr.push(resolveFn)
          this.#onRejectedCalArr.push(rejectFn)

        }
      },0)
    })
    // //2.0加入
    // setTimeout(() => {
    //   //成功态
    //   if (this.#status == this.#itSuccess) {
    //     onFulfilled(this.#theValue)
    //   }
    //   //失败态
    //   else if (this.#status == this.#itError) {
    //     onFulfilled(this.#theValue)
    //   }
    //   //等待态 因为这里可能在promise里面可能还有定时的时候
    //   else {
    //     this.#onFulfilledCalArr.push(() => onFulfilled(this.#theValue)) //加入队列里面
    //     this.#onRejectedCalArr.push(() => onReject(this.#theValue))
    //   }
    // }, 0)
  }
  catch(onRejected) {
    //直接调用上面的
    this.then(null, onRejected)
  }
}
let one = new testPromise((resolve, reject) => {
  console.log("第一个执行")
  setTimeout(() => {
    resolve("时间延迟1s进行resolve我应该是最后一个执行")
    reject("在resolve后面 不会执行的")
  },1000)
})
one.then(res => {

  console.log(res)
  console.log("里面res微任务后执行")
  return "返回了一个简单字符" //这里进行返回一个字符
}, err => {
  console.log(err)
  console.log("reject不会执行的")
}).then(res=>{ //再次调用then
   console.log("再次接收上面then里面返回的值")
  console.log(res)
},err=>{
  console.log(err)
})
console.log("外面宏任务先执行")



[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CyO8z9K2-1667827809851)(记录.assets/image-20221107212543345.png)]

下面是对照组

let two = new Promise((resolve,reject)=>{
  console.log("第一个执行")
  setTimeout(() => {
    resolve("时间延迟1s进行resolve我应该是最后一个执行")
    reject("在resolve后面 不会执行的")
  },1000)
})

//对照组,,
two.then(res => {

  console.log(res)
  console.log("里面res微任务后执行")
  return "返回了一个简单字符"
}, err => {
  console.log(err)
  console.log("reject不会执行的")
}).then(res=>{
  console.log("再次接收上面then里面返回的值")
  console.log(res)
},err=>{
  console.log(err)
})
console.log("外面宏任务先执行")

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4ABF9Sgg-1667827809853)(记录.assets/image-20221107212806443.png)]

所以简单的promise就完成啦,后面就剩下all,和race了啦!简单做个记录咯~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值