手写Promise函数

手写Promise函数

Promise可以说是面试十次八次都要问的知识点,他就是一个解决异步编程的方案,可以进行优雅的链式回调。
什么叫异步编程?
网络上有很多非常解释同步异步编程的学术性话语。我个人的理解:异步编程就是一个很好的时间管理者不浪费每一秒,一直都在干活,停不下来的节奏,不会按照顺序等待这一项工作结束才进行下一项工作,而是只要能抽身便去坐下一项工作,等前一项工作需要他的时候他再回来执行;同步编程就是一个比较死板的过程,必须严格按照顺序,这一项工作完全执行了才会执行下一项工作,这样浏览器会有很多白白等待的时间,非常浪费。
异步编程解决方法
①callback(回调函数),例如AJAX,但是存在许多问题,当嵌套层次深的时候就GG了会出现回调地狱,难以维护;由于每次都是新建立一个栈无法获取以前栈的信息,所以无法正确使用return,throw,没法正常检索以前的堆栈信息;多个回调之间难以建立联系,不知互相状态
②generator+co库
③async+await
④Promise函数
Promise函数图解思想
在这里插入图片描述promise:主要用于异步计算;可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果;可以在对象之间传递和操作Promise,帮助我们处理队列
看了一个官方文档的翻译版本

https://www.ituring.com.cn/article/66566

根据每一个特点与方法翻译出代码,手写了Promise函数如下

class Promise {
    constructor(excutor) {
        //不能相信用户的输入
        //参数校验
        if (typeof excutor!=="function"){
            throw new TypeError(`Promise resolver ${excutor} is not a function`)
            //此处使用的是模板字符串
        }
        this.initValue()
        this.initBind()
        try{
            excutor(this.resolve,this.reject)
        } catch (e) {
            this.reject(e)
        }
        //绑定this
        initBind(){
            this.resolve=this.resolve.bind(this)
            this.reject=this.reject.bind(this)
        }
        initValue() {
            this.value=null //终值
            this.reason=null //拒因
            this.state=Promise.PENDING //状态
            this.onFulfilledCallbacks = [] //成功回调
            this.onRejectedCallbacks = [] //失败回调
        }
        resolve(reason){
            if(this.state==Promise.PENDING){
                this.state=Promise.FULFILLED
                this.value=value
                this.onFulfilledCallbacks.forEach((fn)=>fn(this.value))
            }
        }
        reject(reason){
            if(this.state==PENDING){
                this.state=Promise.REJECTED
                this.reason=reason
                this.onRejectedCallbacks.forEach((fn)=>fn(this.reason))
            }
        }
    }
    then(onFulfilled,onRejected){
        //参数校验
        if (typeof onFulfilled!=="function"){
            onFulfilled=function (value) {
                return  value
            }
        }

    if(typeof onRejected!=="function"){
        onFulfilled=function (reason) {
            throw reason
        }
    }
        //实现链式调用,且改变了后面then的值,必须通过新的实例
        let promise2=new Promise((resolve,reject)=> {
            if (this.state === Promise.FULFILLED) {
               const x= setTimeout(() => {
                   try{
                     const x= onFulfilled(this.value)
                       resolve(x)
                   }catch (e) {
                     reject(e)
                   }
                })
            }
            if (this.state === Promise.REJECTED) {
                setTimeout(() => {
                    try{
                        const x= onRejected(this.reason)
                        resolve(x)
                    }catch (e) {
                       reject(e)
                    }
                })
            }
            if (this.state === Promise.PENDING) {
                this.onFulfilledCallbacks.push(value => {
                    setTimeout(() => {
                        try {
                            const x= onFulfilled(this.value)
                            resolve(x)
                        }catch (e) {
                            reject(e)
                        }
                    })
                })
            this.onRejectedCallbacks.push(reason => {
                setTimeout(() => {
                    try{
                        const x= onRejected(this.reason)
                        resolve(x)
                    }catch (e) {
                     reject(e)
                    }
                })
            })
        }
    })
        return promise2
    }
}
Promise.PENDING='pending'
Promise.FULFILLED='fulfilled'
Promise.REJECTED='rejected'
Promise.resolvePromise=function (promise2,x,resolve,reject) {
    //x与promise相等
    if (promise2===x){
        reject(new  TypeError('Chaining cycle detected for promise'))
    }
    let called=false
    //判断是否为Promise
    if (x instanceof Promise){
       x.then(value => {
           Promise.resolvePromise(promise2,value,resolve.reject)
       },
           reason => {
             reject(reason)
           })
    }else if (x!==null&&(typeof x==='object' || typeof x==='function')){
            //x为对象或方法
        try{
            const then=x.then
            if (typeof x.then === 'function'){
                then.call(x,(value)=>{
                    if (called) return
                    called=true
                    Promise.resolvePromise(promise2,value,resolve.reject)
                },reason => {
                    if (called) return
                    called=true
                    reject(reason)
                })
            }else {
                if (called) return
                called=true
                resolve(x)
            }
        }catch (e) {
            if (called) return
            called=true
            reject(e)
        }
    }else {
        resolve(x)
    }
}

以上!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值