手写Promise

44 阅读1分钟
class MyPromise{
    static FULFILLED = 'fulfilled'
    static REJECTED = 'rejected'
    static PENDING = 'pending'
    constructor(executor){
        this.state = MyPromise.PENDING
        this.value = undefined
        this.reason = undefined
        this.fulfilledCallback = []
        this.rejectedCallback = []
        try{
            executor()
        }catch(err){
            
        }
    }
    _resolve(val){
        if(this.state === MyPromise.PENDING){
            this.state = MyPromise.FULFILLED
            this.value = val
            this.fulfilledCallback.forEach(callback => callback())
        }
    }
    _reject(err){
        if(this.state === MyPromise.PENDING){
            this.state = MyPromise.REJECTED
            this.reason = err
            this.rejectedCallback.forEach(callback => callback())
        }
    }
    then(onFulfilled, onRejected){
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : () => {}
        onRejected = typeof onRejected === 'function' ? onRejected : () => {}
        return new Promise((reso, reje)=>{
            if(this.state === MyPromise.FULFILLED){
                onFulfilled(this.value)
            }
            if(this.state === MyPromise.REJECTED){
                onRejected(this.reason)
            }
            if(this.state === MyPromise.PENDING){
                this.fulfilledCallback.push(onFulfilled)
                this.rejectedCallback.push(onRejected)
            }
        })
    }

    all(arrs) {
        return new Promise((resolve, reject)=>{
            if(!Array.isArray(arrs)) reject(new Error('传参必须为数组'))
            const value = []
            let cnt = arrs.length
            arrs.forEach((element, index) => {
                Promise.resolve(element).then(res=>{
                    value[index] = res
                    cnt--
    
                    if(cnt === 0) resolve(value)
                }).catch(err=>{
                    reject(err)
                })
            });
        })
    }
    
    race(arrs) {
        return new Promise((resolve, reject)=>{
            if(!Array.isArray(arrs)) reject(new Error('传参必须为数组'))
            arrs.forEach((element) => {
                Promise.resolve(element).then(res=>{
                    resolve(res)
                }).catch(err=>{
                    reject(err)
                })
            });
        })
    }
    
    Any(arrs) {
        return new Promise((resolve, reject)=>{
            if(!Array.isArray(arrs)) reject(new Error('传参必须为数组'))
            let cnt = 0
            const reason = []
            arrs.forEach((element, index) => {
                Promise.resolve(element).then(res=>{
                    resolve(res)
                }).catch(err=>{
                    reason[index] = err
                    cnt++
                    if(cnt === arrs.length) reject(reason)
                })
            });
        })
    }
    
    Allsettled(arrs) {
        return new Promise((resolve, reject)=>{
            if(!Array.isArray(arrs)) reject(new Error('传参必须为数组'))
            let res = []
            const cnt = 0
            arrs.forEach((element, index) => {
                Promise.resolve(element).then(res=>{
                    res[index] = { status: "fulfilled", value: res }
                    if(cnt === arrs.length) resolve(res)
                }).catch(err=>{
                    res[index] = { status: "rejected", reason: err }
                    if(cnt === arrs.length) resolve(res)
                })
            });
        })
    }
}