promise 实现

Posted 国服第一李师师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了promise 实现相关的知识,希望对你有一定的参考价值。

1实现异步调用
const PENDDING = \'pendding\',
    RESOLVED = \'resolved\',
    REJECTED = \'rejected\'
	
    class myPromise {
        constructor(handler){
            this.status = PENDDING
            this.value = undefined
            this.resolveCallback = []
            this.rejectCallback = []
            let resolve = (value)=>{
                if(this.status === PENDDING){
                    this.status = RESOLVED
                    this.value = value
                    this.resolveCallback.forEach((cb)=>{
                        cb()
                    })
                }
            }
            let reject = (error)=>{
                if(this.status === PENDDING){
                    this.status = REJECTED
                    this.reason = error
                    this.rejectCallback.forEach((cb)=>{
                        cb()
                    })
                }
            }
            try{
                handler(resolve,reject)
            }catch{
                reject(error)
            }
        }
        then(onResolve=val=>val,onReject){
            if(this.status === PENDDING){
                this.resolveCallback.push(()=>onResolve(this.value))
            }
            if(this.status === RESOLVED){
                onResolve(this.value)
            }
            if(this.status === REJECTED){
                onReject(this.reason)
            }
        }
    }

    new myPromise((resolve)=>{
        setTimeout(()=>{
            resolve(123)
        },2000)
    }).then((res)=>{
        console.log(res)
    })

2.实现 链式调用并返回普通值 主要是promiseResultProduce这个函数

 const PENDDING = \'pendding\',
    RESOLVED = \'resolved\',
    REJECTED = \'rejected\'
    class myPromise {
        constructor(handler){
            this.status = PENDDING
            this.value = undefined
            this.resolveCallback = []
            this.rejectCallback = []
            let resolve = (value)=>{
                if(this.status === PENDDING){
                    this.status = RESOLVED
                    this.value = value
                    this.resolveCallback.forEach((cb)=>{
                        cb()
                    })
                }
            }
            let reject = (error)=>{
                if(this.status === PENDDING){
                    this.status = REJECTED
                    this.reason = error
                    this.rejectCallback.forEach((cb)=>{
                        cb()
                    })
                }
            }
            try{
                handler(resolve,reject)
            }catch{
                reject(error)
            }
        }
        promiseResultProduce(promise2,val,resolve,reject){
            if(val instanceof myPromise){

            }else if((typeof val === \'object\' || typeof val === \'function\')){
                if(typeof val.then === \'function\'){

                }else{
                    resolve(val)
                }
            }else{
                resolve(val)
            }
        }
        then(onResolve=val=>val,onReject){
            if(this.status === PENDDING){
                const promise2 = new myPromise((resolve,reject)=>{
                    this.resolveCallback.push(()=>{
                        let val = onResolve(this.value)
                        setTimeout(()=>{
                            this.promiseResultProduce(promise2,val,resolve,reject)
                        },0)
                    })
                })
                return promise2
            }
            if(this.status === RESOLVED){
                const promise2 = new myPromise((resolve,reject)=>{
                    let val = onResolve(this.value)
                    setTimeout(()=>{
                        this.promiseResultProduce(promise2,val,resolve,reject)
                    },0)
                })
                return promise2
            }
            if(this.status === REJECTED){
                onReject(this.reason)
            }
        }
    }
    
    new myPromise((resolve)=>{
        setTimeout(()=>{
            resolve(123)
        },2000)
    }).then((res)=>res)
    .then((res)=>{
        console.log(res)
        return res
    }).then((res)=>{
        console.log(res)
    })

3 实现 支持promise对象

    const PENDDING = \'pendding\',
    RESOLVED = \'resolved\',
    REJECTED = \'rejected\'
    class myPromise {
        constructor(handler){
            this.status = PENDDING
            this.value = undefined
            this.resolveCallback = []
            this.rejectCallback = []
            let resolve = (value)=>{
                if(this.status === PENDDING){
                    this.status = RESOLVED
                    this.value = value
                    this.resolveCallback.forEach((cb)=>{
                        cb()
                    })
                }
            }
            let reject = (error)=>{
                if(this.status === PENDDING){
                    this.status = REJECTED
                    this.reason = error
                    this.rejectCallback.forEach((cb)=>{
                        cb()
                    })
                }
            }
            try{
                handler(resolve,reject)
            }catch{
                reject(error)
            }
        }
        promiseResultProduce(promise2,val,resolve,reject){
            if(val instanceof myPromise){
                if(val.status === PENDDING){
                    console.log(222)
                    val.then(y=>{
                        console.log(y)
                        this.promiseResultProduce(promise2,y,resolve,reject)
                    },reject)
                }else{
                    /*注意此时val是promise自然有this.value,this.status,this.reason属性*/
                    val.status === RESOLVED && resolve(val.value)
                    val.status === REJECTED && reject(val.reason)
                }
            } else if((typeof val === \'object\' || typeof val === \'function\')){

            } else{
                console.log(1111)
                resolve(val)
            }
        }
        then(onResolve=val=>val,onReject){
            if(this.status === PENDDING){
                const promise2 = new myPromise((resolve,reject)=>{
                    this.resolveCallback.push(()=>{
                        let val = onResolve(this.value)
                        setTimeout(()=>{
                            this.promiseResultProduce(promise2,val,resolve,reject)
                        },0)
                    })
                })
                return promise2
            }
            if(this.status === RESOLVED){
                const promise2 = new myPromise((resolve,reject)=>{
                    let val = onResolve(this.value)
                    this.resolveCallback.push(()=>{
                        setTimeout(()=>{
                            this.promiseResultProduce(promise2,val,resolve,reject)
                        },0)
                    })
                })
                return promise2
            }
            if(this.status === REJECTED){
                onReject(this.reason)
            }
        }
    }

    new myPromise((resolve)=>{
        setTimeout(()=>{
            resolve(123)
        },2000)
    })
    .then((res)=>{
        console.log(res)
        return new myPromise((resolve,reject)=>{
            setTimeout(()=>{
                resolve(666)
            },2000)
        })
    })
    .then((res)=>{
        console.log(res)
    })

4支持thenable对象

    const PENDDING = \'pendding\',
    RESOLVED = \'resolved\',
    REJECTED = \'rejected\'
    class myPromise {
        constructor(handler){
            this.status = PENDDING
            this.value = undefined
            this.resolveCallback = []
            this.rejectCallback = []
            let resolve = (value)=>{
                if(this.status === PENDDING){
                    this.status = RESOLVED
                    this.value = value
                    this.resolveCallback.forEach((cb)=>{
                        cb()
                    })
                }
            }
            let reject = (error)=>{
                if(this.status === PENDDING){
                    this.status = REJECTED
                    this.reason = error
                    this.rejectCallback.forEach((cb)=>{
                        cb()
                    })
                }
            }
            try{
                handler(resolve,reject)
            }catch{
                reject(error)
            }
        }
        promiseResultProduce(promise2,val,resolve,reject){
            if(val instanceof myPromise){
                if(val.status === PENDDING){
                    val.then(y=>{
                        this.promiseResultProduce(promise2,y,resolve,reject)
                    },reject)
                }else{
                    /*注意此时val是promise自然有this.value,this.status,this.reason属性*/
                    val.status === RESOLVED && resolve(val.value)
                    val.status === REJECTED && reject(val.reason)
                }
            } else if((typeof val === \'object\' || typeof val === \'function\')){
                if(typeof val.then === \'function\'){
                    val.then(y=>{
                        this.promiseResultProduce(promise2,y,resolve,reject)
                    },reject)
                }else{
                    resolve(val)
                }
            } else{
                resolve(val)
            }
        }
        then(onResolve=val=>val,onReject){
            if(this.status === PENDDING){
                const promise2 = new myPromise((resolve,reject)=>{
                    this.resolveCallback.push(()=>{
                        let val = onResolve(this.value)
                        setTimeout(()=>{
                            this.promiseResultProduce(promise2,val,resolve,reject)
                        },0)
                    })
                })
                return promise2
            }
            if(this.status === RESOLVED){
                const promise2 = new myPromise((resolve,reject)=>{
                    let val = onResolve(this.value)
                    this.resolveCallback.push(()=>{
                        setTimeout(()=>{
                            this.promiseResultProduce(promise2,val,resolve,reject)
                        },0)
                    })
                })
                return promise2
            }
            if(this.status === REJECTED){
                onReject(this.reason)
            }
        }
    }
    // 支持thenable对象
    // let result = {
    //     then(r){
    //         r(444)
    //     }
    // }
    // result.then(y=>{
    //     console.log(y)
    // })

    /*穿透的原理*/
    // new myPromise((resolve)=>{
    //     setTimeout(()=>{
    //         resolve(123)
    //     },2000)
    // }).then((res)=>res).then((res)=>{
    //     console.log(res)
    // })

以上是关于promise 实现的主要内容,如果未能解决你的问题,请参考以下文章

前端面试题之手写promise

澄清 node.js + promises 片段

什么时候然后从Promise.all()的子句运行?

深入 Promise——Promise 实现详解

promise实现原理代码

Promise原理及实现