zoukankan      html  css  js  c++  java
  • js原生方法promise的实现

    一会儿就要回家过年了,再来手写一个promise吧,要不等着下班真的煎熬。。。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <meta name="author" content="杨欣">
        <title>手写promise</title>
    </head>
    
    <body>
    
        <script>
            // 第一版
            // class _Promise {
            //     constructor(handler) {
            //         // 判断参数是否不为函数
            //         if (typeof handler !== 'function') {
            //             throw new TypeError(`${handler} is not a function`)
            //         }
            //         this.state = 'pending'//初始状态
            //         this.value = null//最终返回值
            //         this.reason = null //失败原因
            //         let _this = this;
            //         const resolve = function (value) {
            //             if (_this.state === 'pending') {
            //                 _this.state = 'fulfilled'//改变状态
            //                 _this.value = value//最终返回值赋值
            //                 console.log(_this.value)
            //             }
            //         }
            //         const reject = function (reason) {
            //             if (_this.state === 'pending') {
            //                 _this.state = 'rejected'//改变状态
            //                 _this.reason = reason//失败原因赋值
            //             }
            //         }
            //         handler(resolve, reject)
            //     }
            // }
            // new _Promise((resolve, reject) => {
            //         resolve(12345)
            // })
    
    
            // // 第二版 代码优化,加then方法,模拟异步操作
            // class _Promise {
            //     constructor(handler) {
            //         // 判断参数是否不为函数
            //         if (typeof handler !== 'function') {
            //             throw new TypeError(`${handler} is not a function`)
            //         }
            //         this.initValue()//初始化值
            //         this.bindThis()//绑定this
    
            //         handler(this.resolve, this.reject)
            //     }
            //     bindThis() {
            //         this.resolve = this.resolve.bind(this)
            //         this.reject = this.reject.bind(this)
            //     }
            //     initValue() {
            //         this.state = 'pending'//初始状态
            //         this.value = null//最终返回值
            //         this.reason = null //失败原因
            //     }
            //     resolve(value) {
            //         if (this.state === 'pending') {
            //             this.state = 'fulfilled'//改变状态
            //             this.value = value//最终返回值赋值
            //         }
            //     }
            //     reject(reason) {
            //         if (this.state === 'pending') {
            //             this.state = 'rejected'//改变状态
            //             this.reason = reason//失败原因赋值
            //         }
            //     }
    
            //     then(onFulfilled, onRejected) {
            //         if (typeof onFulfilled !== 'function') {
            //             onFulfilled = function (value) {
            //                 return value
            //             }
            //         }
    
            //         if (typeof onRejected !== 'function') {
            //             onRejected = function (reason) {
            //                 throw reason
            //             }
            //         }
    
            //         if (this.state === 'fulfilled') {
            //             // 模拟异步
            //             setTimeout(() => {
            //                 onFulfilled(this.value)
            //             }, 1000);
            //         }
    
            //         if (this.state === 'reject') {
            //             setTimeout(() => {
            //                 onRejected(this.reason)
            //             }, 1000);
            //         }
            //     }
            // }
            // new _Promise((resolve, reject) => {
            //     resolve(1234567)
            // }).then((value) => {
            //     console.log(value, 'value')
            // })
            // new _Promise((resolve, reject) => {
            //     setTimeout(() => {
            //         resolve(1234567)
            //     }, 1000);
            // }).then((value) => {
            //     console.log(value, 'value')
            // })//这种情况下then方法中代码不会打印,因为then方法中state为pending,因此需要添加一个状态判断
    
            // 第三版 添加状态判断,添加链式调用(then方法需要返回promise对象)
            class _Promise {
                constructor(handler) {
                    // 判断参数是否不为函数
                    if (typeof handler !== 'function') {
                        throw new TypeError(`${handler} is not a function`)
                    }
                    this.initValue()//初始化值
                    this.bindThis()//绑定this
    
                    try {
                        handler(this.resolve, this.reject)
                    } catch (error) {
                        this.reject(error)
                    }
                }
                bindThis() {
                    this.resolve = this.resolve.bind(this)
                    this.reject = this.reject.bind(this)
                }
                initValue() {
                    this.state = 'pending'//初始状态
                    this.value = null//最终返回值
                    this.reason = null //失败原因
                    this.onFulfilledCbs = []//成功回调
                    this.onRejectedCbs = []//失败回调
                }
                resolve(value) {
                    if (this.state === 'pending') {
                        this.state = 'fulfilled'//改变状态
                        this.value = value//最终返回值赋值
                        // resolve成功执行
                        this.onFulfilledCbs.forEach(fn => fn(this.value))
                    }
                }
                reject(reason) {
                    if (this.state === 'pending') {
                        this.state = 'rejected'//改变状态
                        this.reason = reason//失败原因赋值
                        this.onRejectedCbs.forEach(fn => fn(this.reason))
                    }
                }
    
                then(onFulfilled, onRejected) {
                    if (typeof onFulfilled !== 'function') {
                        onFulfilled = function (value) {
                            return value
                        }
                    }
    
                    if (typeof onRejected !== 'function') {
                        onRejected = function (reason) {
                            throw reason
                        }
                    }
    
                    if (this.state === 'fulfilled') {
                        // 模拟异步
                        setTimeout(() => {
                            onFulfilled(this.value)
                        });
                    }
    
                    if (this.state === 'reject') {
                        setTimeout(() => {
                            onRejected(this.reason)
                        });
                    }
    
                    let promise2 = new _Promise((resolve, reject) => {
                        if (this.state === 'fulfilled') {
                            setTimeout(() => {
                                try {
                                    const data = onFulfilled(this.value)
                                    _Promise.resolvePromise(promise2, data, resolve, reject)
                                } catch (e) {
                                    reject(e)
                                }
                            })
                        }
    
                        if (this.state === 'rejected') {
                            setTimeout(() => {
                                try {
                                    const data = onRejected(this.reason)
                                    _Promise.resolvePromise(promise2, data, resolve, reject)
                                } catch (e) {
                                    reject(e)
                                }
                            })
                        }
    
                        if (this.state === 'pending') {
                            this.onFulfilledCbs.push(value => {
                                setTimeout(() => {
                                    try {
                                        const data = onFulfilled(value)
                                        _Promise.resolvePromise(promise2, data, resolve, reject)
                                    } catch (e) {
                                        reject(e)
                                    }
                                })
                            })
    
                            this.onRejectedCbs.push(reason => {
                                setTimeout(() => {
                                    try {
                                        const data = onRejected(this.reason)
                                        _Promise.resolvePromise(promise2, data, resolve, reject)
                                    } catch (e) {
                                        reject(e)
                                    }
                                })
                            })
                        }
                    })
                    return promise2
                }
            }
            _Promise.resolvePromise = function (promise2, data, resolve, reject) {
                // data 与 promise 相等
                if (promise2 === data) {
                    reject(new TypeError('Chaining cycle detected for promise'))
                }
    
                let flag = false
                if (data instanceof _Promise) {
                    // 判断 data 为 Promise
                    data.then(
                        value => {
                            _Promise.resolvePromise(promise2, value, resolve, reject)
                        },
                        reason => {
                            reject(reason)
                        }
                    )
                } else if (data !== null && (typeof data === 'object' || typeof data === 'function')) {
                    // data 为对象或函数
                    try {
                        const then = data.then
                        if (typeof then === 'function') {
                            then.call(
                                data,
                                value => {
                                    if (flag) return
                                    flag = true
                                    _Promise.resolvePromise(promise2, value, resolve, reject)
                                },
                                reason => {
                                    if (flag) return
                                    flag = true
                                    reject(reason)
                                }
                            )
                        } else {
                            if (flag) return
                            flag = true
                            resolve(data)
                        }
                    } catch (e) {
                        if (flag) return
                        flag = true
                        reject(e)
                    }
                } else {
                    resolve(data)
                }
            }
    
            new _Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(1234567)
                }, 1000);
            }).then((value) => {
                console.log(value, 'value')
                return 11111
            }, (reason) => {
                console.log(reason, 'reason')
            }).then((res) => {
                console.log(res, 'res')
            })
    
    
        </script>
    </body>
    
    </html>
    
  • 相关阅读:
    【C#】解析C#中LING的使用
    【Android】解析Paint类中Xfermode的使用
    【Android】解析Paint类中MaskFilter的使用
    【C#】C#对电子邮件的收发操作
    【Linux】linux/unix下telnet提示Escape character is '^]'的意义
    【Linux】CentOs中yum与rpm区别
    【C#】C#对Excel表的操作
    【SqlServer】解析SqlServer中的事务
    【Android】Android传感器
    【SqlServer】SqlServer的异常处理
  • 原文地址:https://www.cnblogs.com/samsara-yx/p/12217818.html
Copyright © 2011-2022 走看看