有关promise源码的书写第一部分,带api,prototype.finally,静态方法,resolve,reject,race

我们对于掌握promise的写法有好多种,就和业务的实现方式是一样的,当然每个人对于这个东西的理解也有所不同。但只要你是对的,符合promiseA+规范,相信别人是可以看懂的。写promise源码很重要的一点是要有全局观,大局观。这个是什么意思呢,分享一个我自己的故事,我接触promise源码已经有好长时间了,从最初简单的农村promise源码的实现,到现在城市promise的实现,其实我个人的观点有很大的改变,所以我会尽量模仿别人写的那种,忘掉我原来自己看到或者学到的promise.这也是我分享promise的一个原因。

<script>
        const PENDDING = 'pendding'
        const REJECTED = 'rejected'
        const RESOLVED = 'resolved'
        class myPromise{
            constructor(handle){
                this.status = PENDDING
                this.value = undefined
                this.reason = undefined
                this.resolveCallback = []
                this.rejectCallback = []
                let resolve = (val)=>{
                    if(this.status == PENDDING){
                        this.status = RESOLVED
                        this.value = val
                        this.resolveCallback.forEach(fn=>fn())
                    }
                }
                let reject = (error)=>{
                    if(this.status == PENDDING){
                        this.status = REJECTED
                        this.reason = error
                        this.rejectCallback.forEach(fn=>fn())
                    }
                }
                try{    
                    handle(resolve,reject)
                }catch(error){
                    reject(error)
                }
            }
            then(onResolve,onReject){
                if(this.status == RESOLVED){
                    onResolve(this.value)
                }
                if(this.status == REJECTED){
                    onReject(this.reason)
                }
                if(this.status == PENDDING){
                    this.resolveCallback.push(()=>{onReject(this.value)})
                    this.rejectCallback.push(()=>{onReject(this.reason)})
                }
            }
        }
        const p = new myPromise((resolve,reject)=>{
            setTimeout(()=>{
                resolve(111)
            },0)
        }).then((res)=>{
            console.log(res)
        },(err)=>{
            console.log(err)
        })
    </script>
 
老铁们不要着急,上来就粘代码?什么烂博客?哈哈,
我说一下这个的运用场景。他支持你正常的promise里面有异步。then可以使用,报错可以捕获。仅仅而已,不支持链式调用。
解释一下,then里面三种场景:他把所有的情况都考虑进去了,pendding,resolve,reject.一开始看到这种分类写法我就被他吸引了,如果你自己写过简单的promise,我相信你也会被这个分类写法吸引。
这里面用到是简单的发布订阅模式。(与观察者模式有一点点区别,我的上一篇博客就是观察者模式)
 
这里面的精髓就是如何知道promise里面是异步还是同步,
那么大家知道如果是异步他会先去执行then函数,那么可想此时的status == PENDDING
 
也就是我们then,then里面有两个参数,一个成功的回调,一个失败的回调,
我们不管他是成功的回调,还是失败的回调,只要他执行then函数,我们就把我们事先准备好的两个数组里面push东西,终于
 
this.resolveCallback.push(()=>{onReject(this.value)})      ------------>把我们成功的回调包装成一个函数,放进一个数组
this.rejectCallback.push(()=>{onReject(this.reason)})  ------------>把我们失败的回调包装成一个函数,放进一个数组
 
执行完这两条代码后,发现我们有宏任务,开始执行异步代码。当异步结束后,resolve(111)这是status变为了RESOLVED,遍历resolveCallback这个数组,这个数组中的第一项就是一个函数,执行后也就是我们成功的回调执行了,OH YEAR
promise里面有异步我们就实现了
 
 
我们想想当promise里面是同步的时候,我们直接resolve(111),status直接变为RESOLVED,执行then的时候我们发现他的status是RESOLVED,我们直接走成功的回调就ok了
 
下面来看下promise.finally的实现:
 

由第一个promise.resovle那个例子知道resolve的data最后还通过then返回,可想到 

Promise.resolve(callback()).then(()=>data)
由第二个promise.reject那个例子知道里面必然是 throw err 了,而且还可以通过then返回,可想到
Promise.resolve(callback()).then(()=>{throw err})
一起来看下真正的写法:
Promise.finally = function(callback){
    return this.then(data=>{
        return Promise.resolve(callback()).then(()=>data)
    },err=>{
        return Promise.resolve(callback()).then(()=>{throw err})
    })
}
callback是个普通值或者promise ,Promise.resolve的作用:包裹成promise

静态方法resolve ,reject ,race 

resolve :两种情况一种参数是promise,另一种不是。如果是promise 

 
Promise.resolve(111)
Promise.resolve(new Promise((resolve)=>{resolve(1111)}))
 
可想到
static resolve(value){
    if(value instanceof Promise){
        return value
    }else{
        return new Promise((resolve,reject)=>resolve(value))
    }
}
Promise.reject(123)
 
static reject(value){
    return new Promise((resolve,reject)=>reject(value))
}
这两个是不是很简单啊,哈哈
再看下race的实现,简单说下这个api,这个race方法参数是数组,返回最快的那个返回的结果,因为数组中的参数有可能是promise也有可能不是promise,不过返回的总是最快的那个
static race(list){
    return new Promise((resolve,reject)=>{
        for(let k of list){
            this.resolve(list[k]).then(data=>{
                resolve(data)
            },err=>{
                reject(err)
            })
        }
    })
}
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/MDGE/p/12530540.html