promise源码解析之手写源码

  • promise源码解析之手写源码
  • 如何实现手写promise那我们必须要了解a+规范,在上一节,我们已经将a+规范简单的梳理了一遍,下面我们带着a+规范,将promise手写一遍逻辑
  1. *规范-:*需要定义三种状态—pedding/fulfiled/reject
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
  1. 已经定义好了三种状态,接下来需要对状态进行初始化
class ModelPromise{
    constructor(callback){
            this.status = PENDING // 状态初始化
            this.value = null //成功后参数值
            this.reason = null // 失败后的参数值
    }
}
  1. 上面已经做好了前期准备,接下来就需要知道,进行状态机的改变,三种状态:pending, fulfilled, rejected,只有pending可以改变,其他两种皆不可改变,所以我们需要对promise的状态进行改变,通过resolve或者reject方法进行改变,那就需要判断status值是不是pedding,只需要在pendding状态下才可以变化;
class ModelPromise{
    constructor(callback){
            try {
                // 执行回调
                callback(this.resolve.bind(this), this.reject.bind(this))
            } catch (error) {
                this.reject(error)
            }
    }
    resolve(value){
            if(this.status === PENDING){
                this.value = value // 先更新value 
                this.status = FULFILLED // 在更新状态
            }
    }
    reject(reason){
        if(this.status === PENDING){
            this.reason = reason
            this.status = REJECTED
        }
    }
}
  1. 上面的方法写的基本都是同步构造函数,那接下来如何实现.then函数这也是个异步微任务,首先我们也得知道then方法存在两个回调onFulfilledonRejected回调,这个回调只能被执行一次在then方法里实现一个微任务方法
  • 4.1先判断onFulfilledonRejected是不是函数,不是函数,对值进行透传
then(onFullFiled, onRejected){
    const onRealFullFiled =  this.isFunction(onFullFiled) ?onFullFiled:(value)=>value
    const onRealRejected = this.isFunction(onRejected)?onRejected:(reason)=>{ throw reason }
}
  • 4.2 规范中,需要返回一个新的promise,先根据状态status值,调用对应的状态方法
then(onRealFullFiled, onRealRejected){
    ...
     const promise2 = new ModelPromise((resolve, reject)=>{
                switch (this.status){
                    case FULFILLED:{
                        onRealFullFiled()
                        break;
                    }
                    case REJECTED:{
                        onRealRejected()
                        break;
                    }
                }
            })
            return promise2
}

  • 4.3 当状态还没有到达最终态时,这个我们需要定义一个队列进行存储,然后监听状态值,执行队列里的对应的方法
 fulFiledList = []
 rejectList = []
 #status = PENDING
 get(){}
 set(){} //监听状态值的变化
then(onRealFullFiled, onRealRejected){
    ...
     const promise2 = new ModelPromise((resolve, reject)=>{
                switch (this.status){
                    case FULFILLED:{
                        onRealFullFiled()
                        break;
                    }
                    case REJECTED:{
                        onRealRejected()
                        break;
                    }
                    case PENDING:{
                        this.fulFiledList.push(onMicroTaskRealFullFiled)
                        this.rejectList.push(onMicroTaskRealReject)
                        break;
                    }
                    default:{
                        break;
                    }
                }
            })
            return promise2
}

  • 4.4 通过监听状态进行执行队列,采用getter 和setter方法进行监听状态值的变化
 ...
#status = PENDING
 get(){
     return this.#status
 }
 set(value){ //监听状态值的变化
     this.value = value
      switch(value){
                case FULFILLED:{
                    this.fulFiledList.forEach(fn=>{
                        fn(this.value)
                    })
                    break;
                }
                case REJECTED:{
                    this.rejectList.forEach(fn=>{
                        fn(this.reason)
                    })
                    break;
                }
                default:{
                    break;
                }
            }
 } 
  • 4.5 现在目前都还是同步,加入异步方法通过setTimeout或者queueMicrotask进行异步执行
 then(onFullFiled, onRejected){
           ...
            const promise2 = new ModelPromise((resolve, reject)=>{
                 // 微任务
                    const onMicroTaskRealFullFiled = ()=>{
                        queueMicrotask(()=>{
                            try {
                                onRealFullFiled(this.value)
                             } catch (error) {
                                 reject(error)
                             }
                        })
                    }
                    const onMicroTaskRealReject = ()=>{
                        queueMicrotask(()=>{
                            try {
                                onRealRejected(this.reason)
                                this.resolvePromise(promise2, x, resolve, reject)
                            } catch (error) {
                                reject(error)
                            }
                        })
                    }
                switch (this.status){
                    // 同4.3
                    ...
                }
            })
            return promise2
        }
  • 4.6 到目前为止,简易的promise已经处理的差不多了,当然还有onFulfilledonRejected这个两个回调函数处理,和then方法新生成的promise进行处理,处理新生成的Promise和x(回调返回值),判断这两个值的关系进行,如果x是一个promise实例,则进行进行递归解析promise,直到不再是promise为止;判断x是一个对象或者方法,进行解析,加入标志进行判断避免多次执行回调;
  • 4.7 返回promise进行链式调用
  1. catch方法,这个就简单了,通过调用then防范实现
catch(onReject){
        return this.then(null, onReject)
}
  1. 接下来为大家实现两个race和all方法,通过promise使用,我们都知道这两个是静态方法
  • 6.1 race方法:只要其中有一个promise通过就可执行
 static race(values){
    return new ModelPromise((resolve, reject)=>{
        if(values.length === 0){
            return  resolve()
        }
        for(let i = 0; i<values.length;i++){
            ModelPromise.resolve(values[i]).then(res=>{
                return resolve(value);
            }, (reason)=>{
                return reject(reason)
            })
        }
    })
}
  • 6.2 all方法:需要所有的promise执行通过就行
static all(list){
    if(list.length===0){
        return new ModelPromise((resolve)=>resolve())
    }
    return new ModelPromise((resolve)=>{
        let values = []
        for (let i= 0;i<list.length;i++){
            if(list[i] instanceof ModelPromise){
                list[i].then(res=>{
                    values.push(res)
                    if(values.length === i+1){
                        resolve(values)
                    }
                })
            }
            else{
                queueMicrotask(()=>{
                    values.push(list[i])
                    if(values.length === i+1){
                        resolve(values)
                    }
                })
            }
        }
    })
}
  • 总结:promise他是then方法后返回一个新的promise实例跟new 构造函数的promise不是同一个实例,里面函数队列实现,为了实现同一个实例的调用一个then方法,关键区别promise生成新的实例而已。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值