Promise

作者: jiangzj | 来源:发表于2018-11-13 23:28 被阅读0次

    更新

    最近看到一个实现,讲得更加清晰,于是重新实现了一遍

    class GePromise {
        constructor(fn) {
            this.state = 'pending'
            this.value = undefined
            this.resolvedCb = []
            this.rejectedCb = []
    
            let self = this
            try {
                let resolve = self.__resolve.bind(self)
                let reject = self.__reject.bind(self)
                fn(resolve, reject)
            } catch (e) {
                self.__reject(e)
            }
        }
        __resolve(value) {
            let self = this
            if (value instanceof GePromise) {
                return value.then(self.__resolve, self.__reject)
            }
            setTimeout(() => {
                self.state = 'resolved'
                self.value = value
                self.resolvedCb.forEach(cb => cb())
            }, 0)
        }
        __reject(reason) {
            let self = this
            setTimeout(() => {
                self.state = 'rejected'
                self.value = reason
                self.rejectedCb.forEach(cb => cb())
            }, 0)
        }
        then(onResolved, onRejected) {
            let self = this
            let state = this.state
            let newPromise
            if (state === 'resolved') {
                newPromise = new GePromise((resolve, reject) => {
                    setTimeout(() => {
                        try {
                            let x = onResolved(self.value)
                            self.value = x
                            resolve(x)
                        } catch (reason) {
                            reject(reason)
                        }
                    }, 0)
                })
            } else if (state === 'rejected') {
                newPromise = new GePromise((resolve, reject) => {
                    setTimeout(() => {
                        try {
                            let x = onRejected(self.value)
                            self.value = x
                            resolve(x)
                        } catch (reason) {
                            reject(reason)
                        }
                    }, 0)
                })
            } else if (state === 'pending') {
                newPromise = new GePromise((resolve, reject) => {
                    self.resolvedCb.push(() => {
                        try {
                            let x = onResolved(self.value)
                            self.value = x
                            resolve(x)
                        } catch (reason) {
                            reject(reason)
                        }
                    })
                    self.rejectedCb.push(() => {
                        try {
                            let x = onRejected(self.value)
                            self.value = x
                            resolve(x)
                        } catch (reason) {
                            reject(reason)
                        }
                    })
                })
            }
            return newPromise
        }
    }
    
    
    const simpleTest = () => {
        let a = new GePromise((res, rej) => {
            setTimeout(() => {
                console.log('set timeout')
                res('resolve')
            }, 1000)
        })
        let b = a.then((res) => {
            console.log(res) // resolve
            return 'after resolve'
        }, (rej) => {
            console.error(rej)
            return 'first reject'
        }).then(res => {
            console.log(res) // after resolve
        })
    }
    

    原文

    之前看到朋友实现了一个promise,觉得挺好玩的,心中跃跃欲试,于是近期看了一些文章,自己也跟着实现了一遍,记录下来。
    promise是为了解决回调地狱,它是通过then方法来注册回调函数,使得代码在组织上更加清晰。

    一个简单的雏形:

    class GePromise {
        constructor(fn) {
            this.value = null
            this.callbacks = []
            this.init(fn)
        }
        init(fn) {
            const self = this
            const resolve = function(value) {
                self.callbacks.forEach((callback) => {
                    callback(value)
                })
            }
            fn(resolve)
        }
        then(fn) {
            this.callbacks.push(fn)
            return this
        }
    }
    
    const test_1 = function () {
        const p = new GePromise((resolve, reject) => {
            setTimeout(() => {
                resolve(1)
            }, 1000)
            console.log(2)
        })
        p.then((val) => {
            console.log(val)
        })
    }
    test_1()
    

    这时候会有一个问题,有可能在then注册好回调之前,resolve就执行了,因此加入延时机制:

    ...
    const resolve = function(value) {
        setTimeout(() => {
            self.callbacks.forEach((callback) => {
                callback(value)
            })
        }, 0)
    }
    ...
    

    引入状态控制:

    class GePromise {
        constructor(fn) {
            this.state = 'pending'
            this.value = null
            this.callbacks = []
            this._init(fn)
        }
        _init(fn) {
            const resolve = this._resolve.bind(this)
            fn(resolve)
        }
        _resolve(value) {
            const self = this
            self.value = value
            self.state = 'fulfilled'
            setTimeout(() => {
                self.callbacks.forEach((callback) => {
                    callback(value)
                })
            }, 0)
        }
        then(fn) {
            if (this.state === 'pending') {
                this.callbacks.push(fn)
            } else {
                const val = this.value
                fn(val)
            }
            return this
        }
    }
    
    const test = function () {
        const p = new GePromise((resolve, reject) => {
            setTimeout(() => {
                resolve(1)
            }, 1000)
            console.log(2)
        })
        p.then((val) => {
            console.log(val)
        })
        setTimeout(() => {
            p.then((val) => {
                console.log(3)
            })
        }, 3000)
    }
    test()
    

    最后加入reject:

    class GePromise {
        constructor(fn) {
            this.state = 'pending'
            this.value = null
            this.successCb = []
            this.errorCb = []
            this._init(fn)
        }
        _init(fn) {
            const resolve = this._resolve.bind(this)
            const reject = this._reject.bind(this)
            fn(resolve, reject)
        }
        _resolve(value) {
            const self = this
            self.value = value
            self.state = 'fulfilled'
            setTimeout(() => {
                self.successCb.forEach((callback) => {
                    callback(value)
                })
            }, 0)
        }
        _reject(reason) {
            const self = this
            self.value = reason
            self.state = 'rejected'
            setTimeout(() => {
                self.errorCb.forEach((callback) => {
                    callback(reason)
                })
            }, 0)
        }
        then(fn) {
            if (this.state === 'pending') {
                this.successCb.push(fn)
            } else {
                const val = this.value
                fn(val)
            }
            return this
        }
        catch(fn) {
            if (this.state === 'pending') {
                this.errorCb.push(fn)
            } else {
                const val = this.value
                fn(val)
            }
            return this
        }
    }
    

    相关文章

      网友评论

          本文标题:Promise

          本文链接:https://www.haomeiwen.com/subject/nuvrfqtx.html