• 有关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)
                })
            }
        })
    }
     
     
     
     
     
     
  • 相关阅读:
    Leetcode36--->Valid Sudoku(判断给定的数独是否有效)
    Leetcode34--->Search for a Range(在排序数组中找出给定值出现的范围)
    Leetcode33--->Search in Rotated Sorted Array(在旋转数组中找出给定的target值的位置)
    Leetcode31--->Next Permutation(数字的下一个排列)
    Leetcode30--->Substring with Concatenation of All Words(主串中找出连接给定所有单词的子串的位置)
    Leetcode207--->课程表(逆拓扑排序)
    Leetcode28--->字符串的匹配(KMP)
    前端组件,框架,以及模板
    wpf开发
    UML统一建模
  • 原文地址:https://www.cnblogs.com/MDGE/p/12530540.html
Copyright © 2020-2023  润新知