【javaScript 笔记】Promise 实现

/**
 * then onResolved成功回调函数,onRejected失败回调函数
 */

const PENDING = 'pending',REJECTED = 'rejected',FULFILLED='fulfilled'
function MyPromise(executor){
    let self = this
    self.status = PENDING
    self.value = undefined
    self.onResolvedCallback = []
    self.onRejectedCallback = []
    function resolve(value){
        setTimeout(()=>{
            if(self.status === PENDING){
                self.status = FULFILLED
                self.value = value
                for(let i = 0; i < self.onResolvedCallback.length; i++) {
                    self.onResolvedCallback[i](value)
                }
            }
        },0)
    }
   function reject(reason){
        setTimeout(()=>{
            if(self.status === PENDING){
                self.status = REJECTED
                self.value = reason
                for(let i = 0; i < self.onRejectedCallback.length; i++) {
                    self.onRejectedCallback[i](reason)
                }
            }
        },0)
    }
    try {
        executor(resolve,reject)
    }catch(e){
        reject(e)
    }
}
MyPromise.prototype.then = function(onResolved,onRejected){
    let self = this
    onResolved = typeof onResolved === 'function' ? onResolved : function(v) {return v}
    onRejected = typeof onRejected === 'function' ? onRejected : function(r) {throw r}
    function resolveHandler(obj) {
        let {self,onResolved,resolve,reject} = obj
        try{
            let x = onResolved(self.value)
            if(x instanceof MyPromise) {
                x.then(resolve, reject)
            }else{
                resolve(x)
            }
        }catch(e){
            reject(e) 
        }
    }
    function rejectHandler(obj) {
        let {self,onRejected,resolve,reject} = obj
        try{
            let x = onRejected(self.value)
            if(x instanceof MyPromise) {
                x.then(resolve, reject)
            }else {
                reject(x)
            }
        }catch(e){
            reject(e) 
        }
    }
    switch(self.status){
        case FULFILLED: 
            return new MyPromise((resolve,reject)=>{
                resolveHandler.call(self,{self,onResolved,resolve,reject})   
            })
        case REJECTED: 
            return new MyPromise((resolve,reject)=>{
                rejectHandler.call(self,{self,onRejected,resolve,reject})
            })
        case PENDING: 
            return new MyPromise((resolve,reject)=>{
                self.onResolvedCallback.push(resolveHandler.bind(self,{self,onResolved,resolve,reject}))
                self.onRejectedCallback.push(rejectHandler.bind(self,{self,onRejected,resolve,reject}))
            })
    }
}
MyPromise.prototype.catch = function(onRejected) {
    return this.then(null, onRejected)
}
MyPromise.all = function(args) {
    return new MyPromise((resolve,reject)=>{
        let values = [],count = args.length
        while(args.length > 0) {
            args.shift()
            .then((v)=>{
                count --
                values.push(v)
                if(count === 0) resolve(values)
            })
            .catch((e)=>{reject(e)})
        }
    })
}
MyPromise.resolve = function(v) {
    return new MyPromise((resolve,reject)=>{resolve(v)})
}
MyPromise.reject = function(v) {
    return new MyPromise((resolve,reject)=>{reject(v)})
}


// test
let promise1 = new MyPromise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(1)
    },100)
}).then((v)=>{
   console.log('----v----',v)
   return MyPromise.resolve(v)
}).then(v2=>{
    console.log('----v2----',v2) 
    return MyPromise.reject(v2)
}).catch(e=>console.log(e))
let promise2 = new MyPromise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(2)
    },100)
})
let promise3 = new MyPromise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(3)
    },100)
})
let promise4 = new MyPromise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(4)
    },100)
})
MyPromise.all([promise2,promise3,promise4]).then((v)=>{
    console.log(v)
})
.catch(e=>{console.log(e)})

猜你喜欢

转载自www.cnblogs.com/seny-33/p/12950411.html