首页 > 其他分享 >模拟Promise的功能

模拟Promise的功能

时间:2022-11-30 22:47:27浏览次数:40  
标签:功能 resolve rejectedCallback value reason Promise reject promise 模拟

模拟Promise的功能,  按照下面的步骤,一步一步

1. 新建是个构造函数

2. 传入一个可执行函数 函数的入参第一个为 fullFill函数 第二个为 reject函数; 函数立即执行, 参数函数异步执行
3. 状态一旦更改就不可以变更 只能 pending => fulfilled 或者 pending => rejected
4. then 的时候要处理入参的情况 successCallback 和failCallback 均可能为非函数

  • 默认的 failCallback 一定要将异常抛出, 这样下一个promise便可将其捕获 异常冒泡的目的

5. then 中执行回调的时候要捕获异常 将其传给下一个promise

  • 如果promise状态未变更 则将回调方法添加到对应队列中
  • 如果promise状态已经变更 需要异步处理成功或者失败回调
  • 因为可能出现 回调结果和当前then返回的Promise一致 从而导致死循环问题

6. catch只是then的一种特殊的写法 方便理解和使用
7. finally 特点

  1. 不过resolve或者reject都会执行
  2. 回调没有参数
  3. 返回一个Promise 且值可以穿透到下一个then或者catch

8. Promise.resolve, Promise.reject 根据其参数返回对应的值 或者状态的Promise即可
9. Proise.all 特点

  1. 返回一个Promise
  2. 入参是数组 resolve的情况下出参也是数组 且结果顺序和调用顺序一致
  3. 所有的值或者promise都完成才能resolve 所有要计数
  4. 只要有一个为reject 返回的Promise便reject

10. Proise.race 特点

  1. 返回一个Promise
  2. 入参是数组 那么出参根据第一个成功或者失败的参数来确定
  3. 只要有一个resolve 或者reject 便更改返回Promise的状态

 

const PENDING = 'pending' //等待
const FULFILLED = 'fulfilled' //成功
const REJECTED = 'rejected' //失败

const fulfilledCallback = [] //成功回调函数
const rejectedCallback = []  //失败回调函数

class MyPromise {
   
    constructor (executor) {
        
        try{
            executor(this.resolve, this.reject)
        } catch (e){
            this.reject(e)
        }
    }

    status = PENDING//promise的状态
    value = undefined//成功之后的值
    reason = undefined//失败之后的值
    fulfilledCallback = [] //成功回调函数
    rejectedCallback = []  //失败回调函数
    resolve = value => {
        //如果状态不是等待, 阻止程序继续往下执行
        if(this.status !== PENDING){
            return
        }
        this.status = FULFILLED
        this.value = value
        //判断成功回调是否存在,如果存在, 调用
        // this.fulfilledCallback && this.fulfilledCallback(this.value)
        while(this.fulfilledCallback.length) this.fulfilledCallback.shift()()

    }
    reject = reason => {
        //如果状态不是等待, 阻止程序继续往下执行
        if(this.status !== PENDING){
            return
        }
        this.status = REJECTED
        this.reason = reason
        //判断失败回调是否存在,如果存在, 调用
        // this.rejectedCallback && this.rejectedCallback(this.reason)
        while(this.rejectedCallback.length) this.rejectedCallback.shift()()
    }
    then = (fulfilledCallback, rejectedCallback) => {
        fulfilledCallback = fulfilledCallback ? fulfilledCallback : value => value
        rejectedCallback = rejectedCallback ? rejectedCallback : reason => {throw reason}
        let promise2 = new MyPromise((resolve, reject) => {
            
            //判断状态
            if(this.status === FULFILLED){
                setTimeout(() => {
                    try {
                        //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
                        //如果是普通值,直接调用resolve
                        let x = fulfilledCallback(this.value)
                        //外面加载完,才能获取到promise2,用异步解决
                        resolvePromise(promise2,x,resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                    
                },0)
               
            }else if(this.status === REJECTED){
                
                setTimeout(() => {
                    try {
                        //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
                        //如果是普通值,直接调用resolve
                        let x = rejectedCallback(this.reason)
                        //外面加载完,才能获取到promise2,用异步解决
                        resolvePromise(promise2,x,resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                    
                },0)
            }else{
                //等待状态
                this.fulfilledCallback.push(() => {
                    setTimeout(() => {
                        try {
                            //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
                            //如果是普通值,直接调用resolve
                            let x = fulfilledCallback(this.value)
                            //外面加载完,才能获取到promise2,用异步解决
                            resolvePromise(promise2,x,resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                        
                    },0)
                });
                this.rejectedCallback.push(() => {
                    setTimeout(() => {
                        try {
                            //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
                            //如果是普通值,直接调用resolve
                            let x = rejectedCallback(this.reason)
                            //外面加载完,才能获取到promise2,用异步解决
                            resolvePromise(promise2,x,resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                        
                    },0)
                });
            }
        })
        return promise2
    }

    static all (array) {
        let result= []
        let index = 0;

        return new MyPromise((resolve, reject) => {

            function addData (key, value) {
                result[key] = value
                index++
                if (index === array.length) {
                    resolve(result)
                }
            }

            for (let i = 0; i < array.length; i++) {
                
                if (array[i] instanceof MyPromise) {
                    //promise对象
                    array[i].then(value => addData(i, value), reason => reject(reason))
                } else {
                    //普通值, 放到数组里
                    addData(i, array[i])
                }
            }
        })

    }

    static resolve (value) {
        if(value instanceof MyPromise) return value
        return new MyPromise(resolve => resolve(value))

    }

    finally (callback) {
        return this.then(value => {
            return MyPromise.resolve(callback()).then(() => value)
        }, reason => {
            return MyPromise.resolve(callback()).then(() => {throw reason})
        })

    }

    catch (rejectedCallback) {
        return this.then(undefined, rejectedCallback)
    }

}

function resolvePromise(promise2,x,resolve, reject){

    if(x === promise2){
        return reject(new TypeError('啦啦啦啦'))
    }
    if(x instanceof MyPromise){
        //是promise
        //往下直接传
        x.then(resolve,reject)
    }else{
        //普通值
        resolve(x)
    }
}

module.exports = MyPromise;

 

标签:功能,resolve,rejectedCallback,value,reason,Promise,reject,promise,模拟
From: https://www.cnblogs.com/Young111/p/16940017.html

相关文章

  • 模拟栈
    实现一个栈,栈初始为空,支持四种操作:pushx –向栈顶插入一个数 xx;pop –从栈顶弹出一个数;empty –判断栈是否为空;query –查询栈顶元素。现在要对栈进行 M......
  • 模拟队列
    实现一个队列,队列初始为空,支持四种操作:pushx –向队尾插入一个数 xx;pop –从队头弹出一个数;empty –判断队列是否为空;query –查询队头元素。现在要对队......
  • 我使用过的Linux命令之complete - 强劲的bash参数补全功能
    用途说明在使用bash命令行时,在提示符下,输入某个命令的前面几个字符,然后按TAB键,就会列出以这几个字符开头的命令供我们选择。不光如此,还可以进行参数补全,但只限于文件参数,当......
  • ServletContext-功能-获取MIME类型、域对象、获取文件服务器路径
    ServletContext-功能-获取MIME类型获取MIME类型:MIME类型:在互联网通信过程中定义的一种文件数据类型格式:大类型/小类型text/htmlimage/jpeg获......
  • springcloud之模拟微服务环境
    创建聚合服务1-创建父功能newMavenProject修改pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="......
  • 图观引擎V3.3.4 功能更强、操作更便捷!最新升级一睹为快
    图观™引擎,自去年内测版推出上线以来,已帮助众多合作伙伴开发出自己的数字孪生应用、落地交付数字孪生项目,实现了自身软件产品的全面升级、技术能力的大幅拓展。经过不断的升......
  • Spring Cloud 合约功能(三)
    4.4.消费者存根生成与HTTP部分不同,在消息传递中,我们需要在JAR中发布合约定义一个存根。然后在消费者端解析它,并创建适当的存根路由。如果类路径上有多个框架,则存根运......
  • 多功能手持读数仪VH03如何连接手机蓝牙
    VH03内置有基于SPP(SerialPortProfile)协议的蓝牙接口,蓝牙名称为“VH03”。使用任何支持SPP协议的蓝牙设备均可实现与VH03的连接。当蓝牙建立连接后,可向VH03发送指令进......
  • VH03型手持多功能读数仪参数修改方法
    参数修改有三种实现方法,快捷键修改、参数修改模式和连接上位机指令修改。(1)快捷键修改参数:直接短按专用按键实现某些常用参数的修改,如:【激励方法】按键、【温度传感器类型】......
  • SOLIDWORKS 2023交互设计新功能——协作处理团队数据 简化繁琐操作
    我们即将迎来SOLIDWORKS2023新版本,按照往年惯例,SOLIDWORKS2023版本依旧是推出了10大新功能,作为达索正版代理商,微辰三维已经为大家详细解答了三个SOLIDWORKS2023新功能:​​......