美文网首页
15.promise实现(class)

15.promise实现(class)

作者: 原来哥哥是万家灯火 | 来源:发表于2020-07-03 12:59 被阅读0次

    对外暴露3个实例方法 then、catch、finally
    7个静态方法 resolve、reject、all、race、allSetteled、any、try。
    采用宏任务方式实现(setTimeout)
    核心难点在 then 方法的实现

    export default class MockPromise {
        _state = 'pending';
        _value;
        _callBack = [];
    
        constructor(fn) {
            let resolve = (value) => {
                this._doResolve('fulfilled', value)
            }
            let reject = (error) => {
                this._doResolve('rejected', error)
    
            }
            fn(resolve, reject)
        }
    
        _doResolve(state, value) {
            if (this._state !== 'pending') {
                return
            }
    
            this._state = state;
            this._value = value;
    
            setTimeout(() => {
                if (this._state === 'fulfilled') {
                    this._callBack.forEach(({onFulfilled}) => {
                        onFulfilled && onFulfilled(this._value)
                    })
                }
                if (this._state === 'rejected') {
                    this._callBack.forEach(({onRejected}) => {
                        onRejected && onRejected(this._value)
                    })
                }
            }, 0)
        }
    
        then(fulfilledHandler, rejectedHandler) {
            return new MockPromise((resolve, reject) => {
                this._callBack.push({
                    onFulfilled: value => {
                        let result = fulfilledHandler ? fulfilledHandler(value) : this._value;
                        if (result instanceof MockPromise) {
                            result.then(
                                newValue => {
                                    resolve(newValue)
                                },
                                newError => {
                                    reject(newError)
                                })
                        } else {
                            resolve(result)
                        }
                    },
                    onRejected: error => {
                        let result = rejectedHandler ? rejectedHandler(error) : this._value;
                        if (result instanceof MockPromise) {
                            result.then(
                                newValue => {
                                    resolve(newValue)
                                },
                                newError => {
                                    reject(newError)
                                })
                        } else {
                            reject(result)
                        }
                    }
                })
            })
        }
    
        catch(rejectedHandler) {
            return this.then(null, rejectedHandler)
        }
    
        finally(finalHandler) {
            return this.then(
                (value) => {
                    finalHandler();
                    return value
                },
                (error) => {
                    finalHandler();
                    return error
                }
            )
        }
    
        static resolve(value) {
            return new MockPromise(resolve => {
                resolve(value)
            })
        }
    
        static reject(error) {
            return new MockPromise((resolve, reject) => {
                reject(error)
            })
        }
    
        static all(arr) {
            return new MockPromise((resolve, reject) => {
                let result = [];
                let i = 0;
                for (let p of arr) {
                    let len = arr.length;
                    p = p instanceof MockPromise ? p : MockPromise.resolve(p);
                    p.then(value => {
                        result[i++] = value;
                        if (result.length === len) {
                            resolve(result)
                        }
                    }).catch(error => {
                        reject(error)
                    })
                }
            })
        }
    
        static race(arr) {
            return new MockPromise((resolve, reject) => {
                for (let p of arr) {
                    p = p instanceof MockPromise ? p : MockPromise.resolve(p);
                    p.then(value => {
                        resolve(value)
                    }).catch(error => {
                        reject(error)
                    })
                }
            })
        }
    
        static allSettled(arr) {
            return new MockPromise((resolve, reject) => {
                let result = [];
                let i = 0;
                for (let p of arr) {
                    let len = arr.length;
                    p = p instanceof MockPromise ? p : MockPromise.resolve(p);
                    p.then(value => {
                        result[i++] = {status: 'fulfilled', value: value};
                        if (result.length === len) {
                            resolve(result)
                        }
                    }).catch(error => {
                        result[i++] = {status: 'rejected', reason: error};
                        if (result.length === len) {
                            reject(result)
                        }
                    })
                }
            })
        }
    
        static any(arr) {
            return new MockPromise((resolve, reject) => {
                let result = [];
                let i = 0;
                for (let p of arr) {
                    let len = arr.length;
                    p = p instanceof MockPromise ? p : MockPromise.resolve(p);
                    p.then(value => {
                        resolve(value)
                    }).catch(error => {
                        result[i++] = new Error(error);
                        if (result.length === len) {
                            reject(result)
                        }
                    })
                }
            })
        }
    
        static try(fn) {
            return new MockPromise( (resolve) => {
                resolve(fn())
            })
        }
    }
    
    

    相关文章

      网友评论

          本文标题:15.promise实现(class)

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