手写实现Promise的四个静态方法(resolve、reject、race、all)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        class Promise {
            constructor(executor){
                this.state='pending'//初始化state为等待状态
                this.value=undefined//记录成功的值,将来给.then使用
                this.reason=undefined//记录失败的值,将来给.catch使用
    
                this.OnResolvedCallbacks=[]//成功回调数组
                this.OnRejectedCallbacks=[]//失败回调数组
    
                let resolve=(value)=>{
                    // 只要pending状态,才能被改变
                    if(this.state==='pending'){
                        this.state="fulfilled"//更新状态
                        this.value=value//记录成功的信息
                        // 调用成功数组的函数数组中,存了3个函数,需要遍历执行
                        this.OnResolvedCallbacks.forEach(fn=>fn())
    
                    }
                }
                let reject=(reason)=>{
                    if(this.state==='pending'){
                        this.state='rejected'//更新状态
                        this.reason=reason//记录失败的信息
                        // 调用失败数组的函数数组中,存了3个函数,需要遍历执行
                        this.OnRejectedCallbacks.forEach(fn=>fn())
                    }
                }
                // 如果执行executor报错,直接reject
                try{
                    executor(resolve,reject)
                }catch(err){
                    reject(err)
                }
                
            }
            then(onFulfilled,onRejected){
                let promise2=new Promise((resolve,reject)=>{
                    // 如果状态是成功,则执行onFulfilled
                    if(this.state==='fulfilled'){
                        // 如果状态是成功,则执行onFulfilled
                        setTimeout(()=>{
                            try{
                                let x=onFulfilled(this.value)
                                resolvePromise(x,resolve,reject,promise2)
                            }catch(err){
                                reject(err)
                            }
                        },0)
                    }
                    if(this.state==='rejected'){
                        // 如果状态是失败,则执行onRejected
                        setTimeout(()=>{
                            try{
                                let x=onRejected(this.reason)
                                resolvePromise(x,resolve,reject,promise2)
                            }catch(err){
                                reject(err)
                            }
                        })
                    }
                    // 如果状态是等待,则将onFulfilled和onRejected存入对应的数组中
                    if(this.state==='pending'){
                        // 成功回调数组存放成功的回调函数
                        this.OnResolvedCallbacks.push(()=>{
                            setTimeout(()=>{
                                try{
                                    let x=onFulfilled(this.value)
                                    resolvePromise(x,resolve,reject,promise2)
                                }catch(err){
                                    reject(err)
                                }
                            },0)
                        })
                    
                        // 失败回调数组存放失败的回调函数
                        this.OnRejectedCallbacks.push(()=>{
                            setTimeout(()=>{
                                try{
                                    let x=onRejected(this.reason)
                                    resolvePromise(x,resolve,reject,promise2)
                                }catch(err){
                                    reject(err)
                                }
                            },0)
                        })
                    }
                })
                return promise2
            }
        }   
        function resolvePromise(x,resolve,reject,promise2){
            // 处理循环调用
            if(promise2===x){
                const err=new TypeError('Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise>' )
                return reject(err)
            }
            // 判断x是否是promise对象
            if(x instanceof Promise){
            //     // 是promise对象,则等待x的状态
            //     x.then((value)=>{
            //         resolve(value)
            //     },err=>{
            //         reject(err)
            //     })
            x.then(resolve,reject) 
            }else{
                // 不是promise对象,直接resolve
                resolve(x)
            }
        }
        // 手写实现Promise的四个静态方法
        // resolve方法  reject方法 race方法  all方法
        Promise.resolve=function(value){
            return new Promise((resolve,reject)=>{
                resolve(value)
            })
        }

        Promise.reject=function(reason){
            return new Promise((resolve,reject)=>{
                reject(reason)
            })
        }

        // race方法  多个promise,只要有一个promise成功,就返回成功的promise,失败的则全部失败
        Promise.race=function(promises){
            return new Promise((resolve,reject)=>{
                for(let i=0;i<promises.length;i++){
                    promises[i].then(resolve,reject)
                }
            })
        }

        // all方法  多个promise,全部成功才成功,有一个失败,则全部失败
        Promise.all=function(promises){
            return new Promise((resolve,reject)=>{
                let result=[]
                let count=0
                for(let i=0;i<promises.length;i++){
                    promises[i].then((value)=>{
                        result[i]=value
                        count++
                        if(count===promises.length){
                            resolve(result)
                        }
                    },reject)
                }
            })
        }
        
    </script>
</body>
</html>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值