手写Promise(全面)

手写Promise(包含测试用例)

(1)测试用例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise</title>
    <!-- 构造函数 -->
    <!-- <script src="./Promise.js"></script> -->
    <!-- 类 -->
    <!-- <script src="./Promise类.js"></script> -->
</head>

<body>
    <script>
        // 测试then方法
        // 创建Promise实例对象
        // let p = new Promise((resolve, reject) => {
        //     // setTimeout(() => {
        //     resolve('hahaaa');
        //     // }, 200);
        // });
        // console.log(p)
        // const result =  p.then(value => {
        //     return new Promise((resolve,reject)=>{
        //         resolve('hahayang');
        //     })
        // }, reason => {
        //     console.warn(reason); 
        //     // return new Promise((resolve,reject)=>{
        //     //     reject('haha')
        //     // })
        //     // return 'ok';
        //     throw 'error';
        // });
        // console.log(27,result)

        // 测试catch方法
        // let p = new Promise((resolve,reject)=>{
        //     throw '我戳了';
        // })
        // p.catch(reason => {
        //     console.warn(reason);
        // })

        // 测试catch方法(异常穿透)
        // let p = new Promise((resolve,reject)=>{
        //     throw '我戳了';
        // })
        // p.then()
        // .then(value=>{
        //     console.log(222)
        // }).then(value=>{
        //     console.log(333);
        // }).catch(reason=>{
        //     console.warn(reason,444);
        // })

        // 测试resolve方法
        // const p2 = Promise.resolve('ok')
        // console.log(p2)

        // 测试reject方法
        // const p3_1 = Promise.reject('haha')
        // const p3_2 = Promise.reject(Promise.resolve('我是一个粉刷匠'));
        // console.log(p3_1);
        // console.log(p3_2)

        // 测试all方法
        // const p4_1 = Promise.resolve('ok');
        // const p4_2 = new Promise((resolve,reject)=>{
        //     setTimeout(() => {
        //         resolve('success');
        //     }, 1000);
        // })
        // const p4_3 = new Promise((resolve,reject)=>{
        //     setTimeout(() => {
        //         resolve('我是一个粉刷匠');
        //     }, 500);
        // })
        // const p4 = Promise.all([p4_1,p4_2,p4_3]);
        // console.log(p4);

        // 测试race方法
        // const p5_1 = Promise.resolve('ok');
        // const p5_2 = new Promise((resolve, reject) => {
        //     setTimeout(() => {
        //         resolve('success');
        //     }, 1000);
        // })
        // const p5_3 = new Promise((resolve, reject) => {
        //     setTimeout(() => {
        //         resolve('我是一个粉刷匠');
        //     }, 500);
        // })
        // const p5 = Promise.race([p5_1, p5_2, p5_3]);
        // console.log(p5);

        // then方法回调异步调用
        // let p = new Promise((resolve,reject)=>{
        //     console.log(111)
        //     resolve('ok')
        // })
        // p.then(value=>{
        //     console.log(222)
        // })
        // console.log(333)
        // 111 333 222(先执行同步代码,后执行异步代码)
    </script>
</body>

</html>

(2)构造函数方法

function Promise(executor) {
    // 添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    this.callbacks = [];
    const self = this;
    // 定义resolve方法
    function resolve(data) {
        // 判断状态
        if (self.PromiseState !== 'pending') return;
        // 修改属性值
        self.PromiseState = 'fulfilled';
        self.PromiseResult = data;
        // 调用then方法
        setTimeout(() => {
            self.callbacks.forEach(item => {
                item.onResolved(data);
            });
        });

    }
    // 定义reject方法
    function reject(reason) {
        if (self.PromiseState !== 'pending') return;
        self.PromiseState = 'rejected';
        self.PromiseResult = reason;
        // 调用then方法
        setTimeout(() => {
            self.callbacks.forEach(item => {
                item.onRejected(reason);
            })
        });
    }
    // 同步调用执行器函数
    try {
        executor(resolve, reject);
    } catch (error) {
        reject(error);
    }
}
// 将then方法绑定在Promise原型链上,所有的Promise实例对象都可以调用then方法
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
    // this指向调用zhen方法的实例对象(p)
    const self = this;
    // 如果没有传入onRejected函数,则自定义一个,catch穿透
    if (typeof onRejected !== 'function') {
        onRejected = reason => {
            throw reason
        };
    }
    // 如果没有传入onResolved函数,则自定义一个
    if (typeof onResolved !== 'function') {
        onResolved = value => value;
    }
    return new Promise((resolve, reject) => {
        // 封装函数
        function callback(type) {
            try {
                // 获取回调函数的执行结果
                let result = type(self.PromiseResult);
                // 判断回调函数是否是一个Promise对象实例,
                if (result instanceof Promise) {
                    result.then(value => {
                        resolve(value)
                    }, reason => {
                        reject(reason)
                    })
                } else {
                    // 结果的对象状态为成功
                    resolve(result);
                }
            } catch (error) {
                reject(error)
            }
        }
        // 调用回调函数
        // 成功的回调
        if (this.PromiseState === 'fulfilled') {
            setTimeout(() => {
                callback(onResolved);
            });
        }
        // 失败的回调
        if (this.PromiseState === 'rejected') {
            setTimeout(() => {
                callback(onRejected)
            });
        }
        // 判断pending状态
        if (this.PromiseState === 'pending') {
            // 可能存在一个或多个p.then。
            // 所以将then方法的回调函数存在一个数组中,等reject或resolve方法去调用这些回调函数
            this.callbacks.push({
                onResolved: function () {
                    callback(onResolved);
                },
                onRejected: function () {
                    callback(onRejected);
                }
            })
        }
    })
}
// 添加catch方法
Promise.prototype.catch = function (onRejected) {
    this.then(undefined, onRejected);
}
// 添加resolve方法
Promise.resolve = function (value) {
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            value.then(value => {
                resolve(value)
            }, reason => {
                reject(reason)
            })
        } else {
            resolve(value)
        }
    })
}

// 添加reject方法
Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
        reject(reason);
    })
}

// 添加all方法(如果全是fulfilled则返回一个数组,数组中存放着PromiseResult。
//             如果存在一个或多个rejected,则返回最早的{异步})
Promise.all = function (promises) {
    return new Promise((resolve, reject) => {
        let count = 0;
        let arr = [];
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(value => {
                count++;
                arr[i] = value;
                if (count === promises.length) {
                    resolve(arr);
                }
            }, reason => {
                reject(reason)
            })
        }
    })
}

// 添加race方法,谁先完成返回谁
Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(value => {
                resolve(value)
            }, reason => {
                reject(reason)
            })
        }
    })
}

(3)类方法

class Promise {
    // 构造函数
    constructor(executor) {
        // 添加属性
        this.PromiseState = 'pending';
        this.PromiseResult = null;
        this.callbacks = [];
        const self = this;
        // 定义resolve方法
        function resolve(data) {
            // 判断状态
            if (self.PromiseState !== 'pending') return;
            // 修改属性值
            self.PromiseState = 'fulfilled';
            self.PromiseResult = data;
            // 调用then方法
            setTimeout(() => {
                self.callbacks.forEach(item => {
                    item.onResolved(data);
                });
            });

        }
        // 定义reject方法
        function reject(reason) {
            if (self.PromiseState !== 'pending') return;
            self.PromiseState = 'rejected';
            self.PromiseResult = reason;
            // 调用then方法
            setTimeout(() => {
                self.callbacks.forEach(item => {
                    item.onRejected(reason);
                })
            });
        }
        // 同步调用执行器函数
        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error);
        }
    }
    // 添加then方法
    then(onResolved, onRejected) {
        // this指向调用zhen方法的实例对象(p)
        const self = this;
        // 如果没有传入onRejected函数,则自定义一个,catch穿透
        if (typeof onRejected !== 'function') {
            onRejected = reason => {
                throw reason
            };
        }
        // 如果没有传入onResolved函数,则自定义一个
        if (typeof onResolved !== 'function') {
            onResolved = value => value;
        }
        return new Promise((resolve, reject) => {
            // 封装函数
            function callback(type) {
                try {
                    // 获取回调函数的执行结果
                    let result = type(self.PromiseResult);
                    // 判断回调函数是否是一个Promise对象实例,
                    if (result instanceof Promise) {
                        result.then(value => {
                            resolve(value)
                        }, reason => {
                            reject(reason)
                        })
                    } else {
                        // 结果的对象状态为成功
                        resolve(result);
                    }
                } catch (error) {
                    reject(error)
                }
            }
            // 调用回调函数
            // 成功的回调
            if (this.PromiseState === 'fulfilled') {
                setTimeout(() => {
                    callback(onResolved);
                });
            }
            // 失败的回调
            if (this.PromiseState === 'rejected') {
                setTimeout(() => {
                    callback(onRejected)
                });
            }
            // 判断pending状态
            if (this.PromiseState === 'pending') {
                // 可能存在一个或多个p.then。
                // 所以将then方法的回调函数存在一个数组中,等reject或resolve方法去调用这些回调函数
                this.callbacks.push({
                    onResolved: function () {
                        callback(onResolved);
                    },
                    onRejected: function () {
                        callback(onRejected);
                    }
                })
            }
        })
    }
    // 添加catch方法
    catch (onRejected) {
        this.then(undefined, onRejected);
    }
    // 添加resolve方法
    static resolve(value) {
        return new Promise((resolve, reject) => {
            if (value instanceof Promise) {
                value.then(value => {
                    resolve(value)
                }, reason => {
                    reject(reason)
                })
            } else {
                resolve(value)
            }
        })
    }
    // 添加reject方法
    static reject(reason) {
        return new Promise((resolve, reject) => {
            reject(reason);
        })
    }
    // 添加all方法(如果全是fulfilled则返回一个数组,数组中存放着PromiseResult。
    //             如果存在一个或多个rejected,则返回最早的{异步})
    static all(promises) {
        return new Promise((resolve, reject) => {
            let count = 0;
            let arr = [];
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(value => {
                    count++;
                    arr[i] = value;
                    if (count === promises.length) {
                        resolve(arr);
                    }
                }, reason => {
                    reject(reason)
                })
            }
        })
    }
    // 添加race方法,谁先完成返回谁
    static race(promises) {
        return new Promise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(value => {
                    resolve(value)
                }, reason => {
                    reject(reason)
                })
            }
        })
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值