小白也能手写Promise,前端进阶

第一阶段

一、首先第一步,new Promise查看一下

new Promise()
//对应的我的需要创建一个可以new的类,上面等同于下面,下面为我们手写的promise
class MyPromise()

二、Promise中是有着对应的方法函数

new Promise(()=>{}) 
//上方等同于下方
class MyPromise{constructor(fn){}}

三、测试一下Promise在调用时候是否是立即执行的得出,他里面的函数立即执行的,于是

new Promise(()=>{console.log('他会立即执行');})
//上面等同于下面我的手写
class MyPromise{
    constructor(fn){
        fn()    
        }
}

四、接下来已经初步完成了promise的基本架子了,给自己一点掌声吧。让我们来打印一下Promise有一些什么,我们来添加一下他的参数吧

let p1 =  new Promise(()=>{console.log('他会立即执行');})
console.log(p1);

这里可以以看到,promise 中有着两个参数,分别为状态(PromiseState)以及响应结果(PromiseResult),这么说,我们手写中,也需要添加上这两个状态

class MyPromise{
  PromiseState = "pending" //状态
  PromiseValue = undefined  //返回值
  constructor(fn){
    fn()
  }
}

五、接下来就到了第五步,我们需要来实现一下,promise的resolve以及reject了,从下面可以看到,他函数中需要接收到两个参数,于是...

let p1 =  new Promise((resolve,reject)=>{
   resolve(100)
   reject(100)
})

我需要在手写中接收这两个参数,你说对吗

 constructor(fn){
    fn(函数1,函数2)
  }

于是我class中就要有两个函数对应函数1和函数2,来在类中调用,并且需要使用箭头函数,防止最后调用参数指向window,或者需要手动改变this指向,来让参数绑定到类中

 constructor(fn){
    fn(this.resolve,this.reject)
  }
  resolve=()=>{}
  reject=()=>{}
//也可以是下面这种写法,用bind来改变this指向,不懂的可以自己实操打印就知道了

 constructor(fn){
    fn(this.resolve.bind(this),this.reject.bind(this))
  }
  resolve(){}
  reject(){}

六、我们再运行一下之前new 的promise,看看里面还有啥

  • 再次运行resolve(100)可得出,一个成功的状态,一个是返回的结果

可以看到,成功的方法可以让promise中的状态跟值得到改变,于是

 resolve(val){
    this.PromiseState = "fulfilled"
    this.PromiseValue = val
  }

 同理reject

有个promise的报错,于是我要在reject中加个报错

 throw console.error(val);

 七、promise中的成功和失败,只会调用一个,这个逻辑实现如何实现呢,如下,我执行成功和失败得出的是,只有成功执行,相反,则是只有失败执行

 resolve('success')
   reject('error')

 所以,逻辑上,我的PomiseResult的状态改变,就要阻塞后面函数的执行,于是我加了个判断,reslove需要判断,同理失败的reject也需要判断,这里就不新加reject了(保持文档简洁)。

resolve(val){
    // 状态从pending变为resolved,就不能再继续改变状态
    if(this.PromiseState === "pending"){
      this.PromiseState = "resolved"
      this.PromiseValue = val
    }else{
      return
    }
  }

promise中经常也会在里面进行抛出错误操作,如下,然后打印看看,得出,抛出错误也会把状态改变韦rejected

throw new Error('error')

于是我需要在手写中,捕获错误,并执行失败的回调

  try{
      fn(this.resolve.bind(this),this.reject.bind(this))
    }catch(err){
      this.reject(err)
    }

 觉得不美观,我将状态用常量定义状态了,可以不用

第一阶段完成,给自己一点鼓励吧,woooowwwww 

const PANDING = "pending"
const RESOLVED = "resolved"
const REJECTED = "rejected"

class MyPromise{
  // 对象应该有状态和结果
  PromiseState = PANDING
  PromiseValue = undefined
  constructor(fn){
    try{
      fn(this.resolve.bind(this),this.reject.bind(this))
    }catch(err){
      this.reject(err)
    }
  }
  resolve(val){
    // 状态从pending变为resolved,就不能再继续改变状态
    if(this.PromiseState === PANDING){
      this.PromiseState = RESOLVED
      this.PromiseValue = val
    }else{
      return
    }
  }
  reject(val){
    if(this.PromiseState === PANDING){
      this.PromiseState = REJECTED
      this.PromiseValue = val
    }else{
      return
    }
  }
}

第二阶段:月底前发出来

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值