js-手写promise

// promise一共三种状态,状态一旦改变就不能修改
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REGECTED'
const resolvePromise = (x,promise2,resolve,reject) =>{
    // 处理x导致的promise2是成功还是失败
    // 如果x是普通值直接调用promise2和resolve
    // 如果x是一个promise那么就采用x的状态,并且将结果继续调用promise2的resolve和reject向下传递
    console.log(x,promise2,resolve,reject)
    if(x === promise2){
        return reject(new TypeError('不能自己等待自己完成,出错啦'))
    }
    if(typeof x === 'object' && x !== null || typeof x === 'function'){
        // 有可能是一个promise
        try{
            let then = x.then // 因为用户返回的可能有一个then属性,一取值就报错了
            if(typeof then === 'function'){ // 无法再细化了有then说明就是promise了
                then.call(x,(y)=>{
                    resolve(y)
                },(r)=>{
                    reject(r)
                })
            }else{
                resolve(x) // 直接x作为成功的结果
            }
        }catch(e){
            reject(e)
        }
    }else{ // 一定是一个普通得值,那么直接让这个promise变成成功态
        resolve(x)
    }

}
// 定义promise类
class MyPromise{
    constructor(executor){
        this.value= undefined // value成功的值
        this.reason = undefined  // reason失败的原因
        this.status = PENDING // 当前promise的状态
        this.onResolvedCallbacks = [] // 待执行的回调列表
        this.onRejectedCallbacks = [] // 待执行的失败列表
        const resolve = (value) =>{ // 成功就修改状态执行列表
            if(this.status == PENDING){
                this.value = value
                this.status = FULFILLED
                this.onResolvedCallbacks.forEach(callback => callback(value))
            }
        }
        const reject = (reason) =>{ // 失败修改状态执行列表
            if(this.status == PENDING){
                this.reason = reason
                this.status = REJECTED
                this.onRejectedCallbacks.forEach(callback => callback(reason))
            }
            
        }
        try{
            executor(resolve,reject) // 执行回调
        }catch(e){ // 如果执行时发生了异常就将异常作为失败的原因
            reject(e)
        }
    }
    then(onFulfilled,onRejected){
        // 链式调用的核心 就是处理x 和promise之间的关系
        let promise2 = new Promise((resolve,reject) =>{
            if(this.status == FULFILLED){
                // 用定时器为啦promise可以出来
                setTimeout(()=>{
                    try{
                        let x = onFulfilled(this.value)
                        resolvePromise((x,promise2,resolve,reject))
                    }catch(e){
                        reject(e)
                    }
                },0)
            }
            if(this.status == REJECTED){
                setTimeout(()=>{
                    try{
                        let x = onRejected(this.reason)
                        resolvePromise((x,promise2,resolve,reject))
                    }catch(e){
                        reject(e)
                    }
                },0)
            }
            if(this.status == PENDING){
                // 这时用户没有调用成功或者失败 没有reject和resolve
                this.onResolvedCallbacks.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x = onFulfilled(this.value)
                            resolvePromise((x,promise2,resolve,reject))
                        }catch(e){
                            reject(e)
                        }
                    },0)
                })
                this.onRejectedCallbacks.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x = onRejected(this.reason)
                            resolvePromise((x,promise2,resolve,reject))
                        }catch(e){
                            reject(e)
                        }
                    },0)
                })
            }
        })
        return promise2
    }
}
// 实例方法
MyPromise.prototype.catch = function(reject){
    return this.then(null,reject)
}
MyPromise.prototype.finally = function(cb){
    return this.then((value)=>{
        return MyPromise.resolve(cb()).then(()=>{
            return value
        })
    },(err)=>{
        return MyPromise.resolve(cb()).then(()=>{
            throw err
        })
    })
}
// 静态方法  all allSettled race any resolve reject
MyPromise.prototype.all = function(list){
    let len = list.length
    let result = []
    let count = 0
    return new Promise((resolve,reject)=>{
        for(let p of list){
            Promise.resolve(p).then(res =>{
                result[count] = res
                count++
                if(count === len){
                    resolve(result)
                }
            }).catch(e => {
                reject(e)
            })
            
        }
    })
}
MyPromise.prototype.allSettled = function(list){
    let len = list.length
    let result = []
    let count = 0
    return new Promise((resolve,reject)=>{
        for(let p of list){
            Promise.resolve(p).then(res =>{
                result[count] = {
                    status: 'fulfiled',
                    value: res
                }
                count++
                if(count === len){
                    resolve(result)
                }
            }).catch(e => {
                result[count] = {
                    status: 'rejected',
                    value: e
                }
                count++
                if(count === len){
                    reject(result)
                }
            })
            
        }
    })
}
MyPromise.prototype.any = function(list){
    let len = list.length
    let result = []
    let count = 0
    return new Promise((resolve,reject)=>{
        for(let p of list){
            Promise.resolve(p).then(res =>{
                resolve(res)
            }).catch(e => {
                result[count]= e;
                count++
                if(count === len){
                    reject(result)
                }
            })
            
        }
    })
}

MyPromise.prototype.race = function(list){
    let len = list.length
    let result = []
    let count = 0
    return new Promise((resolve,reject)=>{
        for(let p of list){
            MyPromise.resolve(p).then((value)=>{
                resolve(value)
            },(err)=>{
                reject(err)
            })
        }
    })
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值