手写promise函数

88 阅读2分钟

class MyPromise {
    constructor (executor) {
        // 初始化数据
        this.initValue();
        // 为resolve、reject绑定this
        this.initBind();
        try {
            // 执行函数
            executor(this.resolve, this.reject);
        } catch (e) {
            // 如果执行中报了异常,直接以reject方式返回
            this.reject(e);
        }
    }
    // 初始化数据
    initValue () {
        this.promiseState = 'pending';
        this.promiseResult = null;
        this.onFulfilledCallback = [];
        this.onRejectCallback = [];
    }
    // 为resolve、reject绑定this
    initBind () {
        this.resolve = this.resolve.bind(this);
        this.reject = this.reject.bind(this);
    }
    resolve (value) {
        if (this.promiseState !== 'pending') return;
        this.promiseState = 'fulfilled';
        this.promiseResult = value;
        // 执行resolve的回调队列
        while (this.onFulfilledCallback.length) {
            this.onFulfilledCallback.shift()(this.promiseResult);
        }
    }
    reject (reason) {
        if (this.promiseState !== 'pending') return;
        this.promiseState = 'rejected';
        this.promiseResult = reason;
        // 执行reject的回调队列
        while (this.onRejectCallback.length) {
            this.onRejectCallback.shift()(this.promiseResult);
        }
    }
    then (onfulfilled, onReject) {
        onfulfilled = typeof onfulfilled === 'function' ? onfulfilled : val => val;
        onReject = typeof onReject === 'function' ? onReject : reason => { throw reason; };
        var thenPromise = new MyPromise((resolve, reject) => {
            // 多个then的实现
            const resolvePromise = cb => {
                // 用setTimeout实现异步执行
                setTimeout(() => {
                    try {
                        const x = cb(this.promiseResult);
                        if (x === thenPromise) {
                            throw new Error('不能返回自身');
                        }
                        if (x instanceof MyPromise) {
                            x.then(resolve, reject);
                        } else {
                            resolve(x);
                        }
                    } catch (e) {
                        reject(e);
                        throw new Error(e);
                    }
                });
            };
            if (this.promiseState === 'fulfilled') {
                resolvePromise(onfulfilled);
            } else if (this.promiseState === 'rejected') {
                resolvePromise(onReject);
            } else if (this.promiseState === 'pending') {
                this.onFulfilledCallback.push(resolvePromise.bind(this, onfulfilled));
                this.onRejectCallback.push(resolvePromise.bind(this, onReject));
            }
        });
        return thenPromise;
    }
    // 实现promise.all
    static all (promises) {
        const result = [];
        let count = 0;
        return new MyPromise((resolve, reject) => {
            const addData = (index, value) => {
                result[index] = value;
                count++;
                if (count === promises.length) resolve(result);
            };
            promises.forEach((item, index) => {
                if (item instanceof MyPromise) {
                    item.then(res => {
                        addData(index, res);
                    }, err => reject(err));
                } else {
                    addData(index, item);
                }
            });
        });
    }
    // 实现promise.race
    static race (promises) {
        return new MyPromise((resolve, reject) => {
            promises.forEach((item, index) => {
                if (item instanceof MyPromise) {
                    item.then(res => {
                        resolve(res);
                    }, err => reject(err));
                } else {
                    resolve(item);
                }
            });
        });
    }
    // 实现promise.allSettled
    static allSettled (promises) {
        const result = [];
        let count = 0;
        return new MyPromise((resolve) => {
            let addData = (status, value, index) => {
                result[index] = {
                    status,
                    value
                };
                count++;
                if (count === promises.length) resolve(result);
            };
            promises.forEach((item, index) => {
                if (item instanceof MyPromise) {
                    item.then(res => {
                        addData('fulfilled', res, index);
                    }, err => {
                        addData('rejected', err, index);
                    });
                } else {
                    addData('fulfilled', item, index);
                }
            });
        });
    }
    // 实现promise.any
    static any (promises) {
        let count = 0;
        return new MyPromise((resolve, reject) => {
            promises.forEach(item => {
                if (item instanceof MyPromise) {
                    item.then(res => {
                        resolve(res);
                    }, err => {
                        count++;
                        if (count === promises.length) {
                            reject('全部异常');
                        }
                    });
                } else {
                    resolve(item);
                }
            });
        });
    }
}

async function fn1 () {
    return new MyPromise((resolve, reject) => {
        setTimeout(() => {
            resolve(100);
        }, 1000);
    });
}
async function fn2 () {
    return new MyPromise((resolve, reject) => {
        setTimeout(() => {
            reject(200);
        }, 200);
    });
}
async function fn3 () {
    return 300;
}
function fn4 () {
    return new MyPromise((resolve, reject) => {
        throw ('异常');
    });
}
// Promise.all([fn1(), fn2(), fn3()]).then(res => {
//     console.log(res);
// });
// MyPromise.all([fn1(), fn2(), fn3()]).then(res => {
//     console.log(res);
// });
// MyPromise.race([fn1(), fn2(), fn3()]).then(res => {
//     console.log(res);
// });
MyPromise.any([fn1(), fn2(), fn3(), fn4()]).then(res => {
    console.log(res);
});
// let p1 = new MyPromise((resolve, reject) => {
//     reject(100);
// }).then(res => 2 * res, err => 3 * err)
//     .then(res => console.log('成功', res), err => console.log('失败', err));
// console.log(2);
// let p2 = new MyPromise((resolve, reject) => {
//     reject('失败');
// });

上述关于节流防抖函数的实现是自己学习的记录,更详细的实现方法大家可以看一下看了就会,手写Promise原理,最通俗易懂的版本!!! - 掘金 (juejin.cn)