手写Promise

98 阅读3分钟

1.myPromise基本结构

1.初始化状态、执行传入的函数

2.定义rosolvereject方法

修改promise状态,保存结果/原因

3.定义then方法

(1)参数校验

(2)处理fulfilledrejected状态

class myPromise {
    static PENDING = 'pending'
    static FULFILLED = 'fulfilled'
    static REJECTED = 'rejected'
    constructor(func) {
        // 1.初始化状态
        this.promiseState = myPromise.PENDING
        this.promiseResult = null
        // 2.执行传入的函数,执行过程中出错也要reject
        try {
            func(this.resolve.bind(this), this.reject.bind(this))
        } catch(err) {
            this.reject(err)
        }
    }
    // 2.定义rosolve、reject方法
    resolve(result) {
        if(this.promiseState === myPromise.PENDING) {
            this.promiseState = myPromise.FULFILLED
            this.promiseResult = result
        }
    }
    reject(reason) {
        if(this.promiseState === myPromise.PENDING) {
            this.promiseState = myPromise.REJECTED
            this.promiseResult = reason
        }
    }
    // 3.定义then方法
    then(onFulfilled, onRejected) {
        // 参数校验
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
        // 执行传入then的函数(参数校验后)
        if(this.promiseState === myPromise.FULFILLED) {
            onFulfilled(this.promiseResult)
        }
        if(this.promiseState === myPromise.REJECTED) {
            onRejected(this.promiseResult)
        }
    }
}

2.增加异步

constructoronFulfilledCallbackonRejectedCallbacks暂存then中的回调函数

resolve/reject:增加setTimeout,使得resolve/reject中的代码最后执行。同时需要将onFulfilledCallback/onRejectedCallbacks中暂存的回调函数依次取出执行一遍。

then:增加pending状态下的处理(往onFulfilledCallback/onRejectedCallbacks中存入回调函数)

class myPromise {
    static PENDING = 'pending'
    static FULFILLED = 'fulfilled'
    static REJECTED = 'rejected'
    constructor(func) {
        // 1.初始化状态
        this.promiseState = myPromise.PENDING
        this.promiseResult = null
        this.onFulfilledCallbacks = []
        this.onRejectedCallbacks = []
        // 2.执行传入的函数,执行过程中出错也要reject
        try {
            func(this.resolve.bind(this), this.reject.bind(this))
        } catch(err) {
            this.reject(err)
        }
    }
    // 3. 定义resolve、reject。(作用:修改状态,执行回调函数)
    resolve(result) {
        if(this.promiseState === myPromise.PENDING) {
            setTimeout(() => {
                this.promiseState = myPromise.FULFILLED
                this.promiseResult = result
                // 执行回调函数
                this.onFulfilledCallbacks.forEach((fun) => {
                    fun(result)
                })   
            });
        }
    }
    reject(reason) {
        if(this.promiseState === myPromise.PENDING) {
            setTimeout(() => {
                this.promiseState = myPromise.REJECTED
                this.promiseResult = reason
                // 执行回调函数
                this.onRejectedCallbacks.forEach((fun) => {
                    fun(reason)
            })
            });
        }
    }
    // 4.定义then(then的作用:状态满足时直接执行传入的函数,否则向回调函数数组中添加函数)
    then(onFulfilled, onRejected) {
        // (2)参数校验
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
        // (1)执行传入then的函数(参数校验后)
        if(this.promiseState === myPromise.FULFILLED) {
            // (3)增加异步
            setTimeout(() => {
                onFulfilled(this.promiseResult)    
            });
        }
        if(this.promiseState === myPromise.REJECTED) {
            setTimeout(() => {
                onRejected(this.promiseResult)    
            });
        }
        // (4)增加pending状态的处理
        if(this.promiseState === myPromise.PENDING) {
            this.onFulfilledCallbacks.push(onFulfilled)
            this.onRejectedCallbacks.push(onRejected)
        }
    }
}

// 测试用例
console.log(1);
let promise1 = new myPromise((resolve, reject) => {
    console.log(2);
    setTimeout(() => {
        console.log('A', promise1.promiseState);
        resolve('这次一定');
        console.log('B', promise1.promiseState);
        console.log(4);
    });
})
promise1.then(
    result => {
        console.log('C', promise1.promiseState);
        console.log('fulfilled:', result);
    },
    reason => {
        console.log('rejected:', reason)
    }
)
console.log(3);

3.then的链式调用

class myPromise {
    static PENDING = 'pending'
    static FULFILLED = 'fulfilled'
    static REJECTED = 'rejected'
    constructor(func) {
        // 1.初始化状态
        this.promiseState = myPromise.PENDING
        this.promiseResult = null
        this.onFulfilledCallbacks = []
        this.onRejectedCallbacks = []
        // 2.执行传入的函数,执行过程中出错也要reject
        try {
            func(this.resolve.bind(this), this.reject.bind(this))
        } catch(err) {
            this.reject(err)
        }
    }
    // 3. 定义resolve、reject。(作用:修改状态,执行回调函数)
    resolve(result) {
        if(this.promiseState === myPromise.PENDING) {
            setTimeout(() => {
                this.promiseState = myPromise.FULFILLED
                this.promiseResult = result
                // 执行回调函数
                this.onFulfilledCallbacks.forEach((fun) => {
                    fun(result)
                })
            });
        }
    }
    reject(reason) {
        if(this.promiseState === myPromise.PENDING) {
            setTimeout(() => {
                this.promiseState = myPromise.REJECTED
                this.promiseResult = reason
                // 执行回调函数
                this.onRejectedCallbacks.forEach((fun) => {
                    fun(reason)
                })
            });
        }
    }
    // 4.定义then(then的作用:状态满足时直接执行传入的函数,否则向回调函数数组中添加函数)
    then(onFulfilled, onRejected) {
        // (2)参数校验
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
        const promise2 = new myPromise((resolve, reject) => {
            // (1)执行传入then的函数(参数校验后)
            if(this.promiseState === myPromise.FULFILLED) {
                // (3)增加异步
                setTimeout(() => {
                    try {
                        let x = onFulfilled(this.promiseResult)
                        resolvePromise(promise2, x, resolve, reject); 
                    } catch(err) {
                        reject(err)
                    }
                    
                });
            }
            if(this.promiseState === myPromise.REJECTED) {
                setTimeout(() => {
                    try {
                        let x = onRejected(this.promiseResult)    
                        resolvePromise(promise2, x, resolve, reject)
                    } catch(err) {
                        reject(err)
                    }
                });
            }
            // (4)增加pending状态的处理
            if(this.promiseState === myPromise.PENDING) {
                this.onFulfilledCallbacks.push(() => {
                    try {
                        let x = onFulfilled(this.promiseResult)
                        resolvePromise(promise2, x, resolve, reject)
                    } catch(err) {
                        reject(err)
                    }
                })
                this.onRejectedCallbacks.push(() => {
                    try {
                        let x = onRejected(this.promiseResult)
                        resolvePromise(promise2, x, resolve, reject)
                    } catch(err) {
                        reject(err)
                    }
                })
            }
        })
        return promise2
    }
}

function resolvePromise(promise, x, resolve, reject) {
    if(x === promise) {
        // (1)x和原来的promise是同一个
        return reject(new TypeError('Chaining cycle detected for promise'))
    }
    if(x instanceof myPromise) {
        // (2)x是一个新的promise
        if(x.promiseState === myPromise.PENDING) {
            x.then(
                y => { resolvePromise(promise, y, resolve, reject) },
                reject
            )
        } else if(x.promiseState === myPromise.FULFILLED) {
            resolve(x.promiseResult)
        } else if(x.promiseState === myPromise.REJECTED) {
            reject(x.promiseResult)
        }

    } else if(x !== 'null' && (typeof x === 'object' || typeof x === 'function')) {
        // (3)x是对象或者函数
        try {
            var then = x.then
        } catch(err) {
            return reject(err)
        }
        if(typeof then === 'function') {
            let called = false
            try {
                then.call(
                    x,
                    y => {
                        if(called) return
                        called = true
                        resolvePromise(promise, y, resolve, reject)
                    },
                    r => {
                        if(called) return
                        called = true
                        reject(r)
                    }
                )
            } catch(err) {
                if(called) return
                called = true
                reject(err)
            }
        } else {
            resolve(x)
        }

    } else {
        // (4)其他
        return resolve(x)
    }
}