前端

自己实现一个promise

2020-08-21  本文已影响0人  若年

整理自后盾人网站

class MyPromise {
    static PENDING = "pending";
    static FULFILLED = "fulfilled";
    static REJECTED = "rejected";
    constructor(executor) {
        this.status = MyPromise.PENDING;
        this.value = null;
        this.callbacks = [];
        try {
            executor(this.resolve.bind(this), this.reject.bind(this));
        } catch (error) {
            this.reject(error);
        }
    }
    resolve(value) {
        if (this.status == MyPromise.PENDING) {
            this.status = MyPromise.FULFILLED;
            this.value = value;
            setTimeout(()=>{
                this.callbacks.map(callback => {
                    callback.onFulfilled(value);
                });
            })

        }
    }
    reject(value) {
        if (this.status == MyPromise.PENDING) {
            this.status = MyPromise.REJECTED;
            this.value = value;
            setTimeout(()=>{
                this.callbacks.map(callback => {
                    callback.onRejected(value);
                });
            })
        }
    }
    then(onFulfilled,onRejected){
        if (typeof onFulfilled != "function") {
            onFulfilled = value =>value;;
        }
        if (typeof onRejected != "function") {
            onRejected = value => value;
        }
        return new MyPromise((resolve,reject)=>{
            if(this.status ==MyPromise.PENDING){
                this.callbacks.push({
                    onFulfilled:value=>{
                        this.parse(promise,onFulfilled(this.value), resolve, reject);
                    },
                    onRejected: value => {
                        this.parse(promise,onRejected(this.value), resolve, reject);
                    }
                })
            }
            if (this.status == MyPromise.FULFILLED) {
                setTimeout(() => {
                    this.parse(promise,onFulfilled(this.value), resolve, reject);
                });
            }
            if (this.status == MyPromise.REJECTED) {
                setTimeout(() => {
                    this.parse(promise,onRejected(this.value), resolve, reject);
                });
            }
        });
    }
    parse(promise,result, resolve, reject) {
        if(promise ==result){
            throw new TypeError("Chaining cycle detected for promise");
        }
        try {
            if (result instanceof MyPromise) {
                result.then(resolve, reject);
            } else {
                resolve(result);
            }
        } catch (error) {
            reject(error);
        }
    }
    static resolve(value) {
        return new MyPromise((resolve, reject) => {
            if (value instanceof MyPromise) {
                value.then(resolve, reject);
            } else {
                resolve(value);
            }
        });
    }
    static reject(reason) {
        return new MyPromise((_, reject) => {
            reject(reason);
        });
    }
    static all(promises) {
        let resolves = [];
        return new MyPromise((resolve, reject) => {
            promises.forEach((promise, index) => {
                promise.then(
                    value => {
                        resolves.push(value);
                        if (resolves.length == promises.length) {
                            resolve(resolves);
                        }
                    },
                    reason => {
                        reject(reason);
                    }
                );
            });
        });
    }
    static race(promises) {
        return new MyPromise((resolve, reject) => {
            promises.map(promise => {
                promise.then(value => {
                    resolve(value);
                });
            });
        });
    }
}

使用测试

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="myPromise.js"></script>
<script>
    //使用测试
    let p1 = new MyPromise((resolve, reject) => {
        resolve("测试");
    }).then(value => {
            console.log(value);
        },
        reason => {
            console.log(reason);
        }).then(
        value => {
            console.log(value);
        },
        reason => {
            console.log(reason);
        }
    );
    let p2 = new MyPromise((resolve, reject) => {
        resolve("测试2");
    }).then(value => {
            console.log(value);
        },
        reason => {
            console.log(reason);
        }).then(
        value => {
            console.log(value);
        },
        reason => {
            console.log(reason);
        }
    );;
    MyPromise.resolve("完成").then(value => {
        console.log(value);
    });
    MyPromise.all([p1,p2]).then((value)=>{
        console.log(value);
    })
</script>
</body>
</html>
上一篇下一篇

猜你喜欢

热点阅读