使用class封装promise(js)

376 阅读2分钟

主要实现功能:

  • resolve
  • reject
  • Promise.then
  • Promise.catch
  • Promise.all
  • Promise.reac

思路:

  1. 设定三个状态 PENDING、FULFILLED、REJECTED,只能由PENDING改变为FULFILLED、REJECTED,并且只能改变一次
  2. MyPromise接收一个函数executor,executor有两个参数resolve方法和reject方法
  3. resolve将PENDING改变为FULFILLED
  4. reject将PENDING改变为FULFILLED
  5. promise变为FULFILLED状态后具有一个唯一的value
  6. promise变为REJECTED状态后具有一个唯一的reason
class myPromise {
    //  1、设定3个状态值,只能由PENDING转变成FULFILLED或REJECTED,且只能转变一次。
    #PENDING = 'pending'
    #FULFILLED = 'fulfilled'
    #REJECTED = 'rejected'

    // 2、创建构造函数,传入一个执行器函数executor
    constructor(exector) {
        this.state = this.#PENDING       // 状态存储
        this.value = null                // resolve方法返回的唯一值
        this.reason = null               // reject方法返回的唯一值    
        this.onFulfilledCallBacks = []   // fulfilled状态的回调数组
        this.onRejectedCallBacks = []    // rejected状态的回调数组

        // 执行成功的resolve方法
        const resolve = (value) => {
            if (this.state === this.#PENDING) {
                this.state = this.#FULFILLED
                this.value = value
                this.onFulfilledCallBacks.forEach(fun => {
                    fun()
                })
            }
        }
        // 执行失败的reject方法
        const reject = (reason) => {
            if (this.state === this.#PENDING) {
                this.state = this.#REJECTED
                this.reason = reason
                this.onRejectedCallBacks.forEach(fun => {
                    fun()
                })
            }
        }

        // 尝试调用执行器,错误则调用reject方法
        try {
            exector(resolve, reject)
        } catch (err) {
            reject(err)
        }
    }

    // then方法
    // 通过settimeOut来模拟异步调用,保证链式调用,所以then方法抛出的是一个新的promise,并将返回值进行resolve
    then(onFulfilled, onRejected) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = value => value
        }
        if (typeof onRejected !== 'function') {
            onRejected = reason => reason
        }
        const promise_ = new myPromise((resolve, reject) => {
            switch (this.state) {
                case this.#PENDING:
                    this.onFulfilledCallBacks.push(() => {
                        setTimeout(() => {
                            try {
                                const result = onFulfilled(this.value)
                                resolve(result)
                            } catch (err) {
                                reject(err)
                            }
                        }, 0)
                    })
                    this.onRejectedCallBacks.push(() => {
                        setTimeout(() => {
                            try {
                                const result = onRejected(this.reason)
                                resolve(result)
                            } catch (err) {
                                reject(err)
                            }
                        }, 0)
                    })
                    break
                case this.#FULFILLED:
                    setTimeout(() => {
                        try {
                            const result = onFulfilled(this.value)
                            resolve(result)
                        } catch (err) {
                            reject(err)
                        }
                    }, 0)
                    break
                case this.#REJECTED:
                    setTimeout(() => {
                        try {
                            const result = onRejected(this.reason)
                            reject(result)
                        } catch (err) {
                            reject(err)
                        }
                    }, 0)
                    break
            }
        })
        return promise_
    }

    // catch方法,执行一次then方法的onRejected
    catch(onRejected) {
        return this.then(null, onRejected)
    }

    // finally方法,无论执行结果,返回value或抛出异常reason
    finally(fn) {
        return this.then((value) => {
            fn()
            return value
        }, (reason) => {
            fn()
            throw reason
        })
    }

    // all方法,接收一个promise数组,当所有promise状态都为resolve时执行resolve
    all(promises) {
        return new myPromise((resolve, reject) => {

            if (promises.lngth === 0) {
                resolve([])
            } else {
                const result  = [] // 接受promise返回值
                for (let i = 0; i < promises.length; i++) {
                        promises[i].then(data => {
                        result[i] = data
                        if (++i === promises.length) {
                            resolve(result)
                        }
                    }, (err) => {
                        reject(err)
                        return
                    })
                }
            }
        })
    }

    //reac方法,接受一个promise数组,当有一个promise状态为resolve时执行resolve
    reac(promises) {
        return new myPromise((resolve, reject) => {
            if (promises.lngth === 0) {
                resolve()
            } else {
                for (let i = 0; i < promises.length; i++) {
                    promises[i].then(data => {
                        resolve(data)
                    }, reason => {
                        reject(reason)
                        return
                    })
                }
            }
        })
    }
}

测试:

function test(type) {
    return new myPromise((resolve, reject) => {
        switch (type) {
            case 'resolve':
                resolve('resolve is success !')
                break
            case 'reject':
                reject('reject is success !')
                break
            case 'finallyResolve':
                resolve('finallyResolve is success !')
                break
            case 'finallyReject':
                reject('finallyReject is success !')
                break
        }
    })
}
const fn1 = test('resolve')
fn1.then(e => {
    console.log(e)
})
// 输出: resolve is success !

const fn2 = test('reject')
fn2.catch(e => {
    console.log( e)
})
// 输出: 'reject is success !


const fn3 = test('finallyResolve')
fn3.then(e => {
    console.log(e)
}).finally(e => {
    console.log('finally is success !')
})
// 输出: finallyResolve is success !
// 输出: finally is success !

const fn4 = test('finallyReject')
fn4.catch(e => {
    console.log(e)
}).finally(e => {
    console.log('finally is success !')
})
// 输出: finallyReject is success !
// 输出: finally is success !

new myPromise().all([fn1, fn3]).then(e => {
    console.log('promiseAll', e)
})
// 输出: promiseAll [ 'resolve is success !', 'finallyResolve is success !' ]

new myPromise().reac([fn1, fn2]).then(e => {
    console.log('promissReac', e)
})
// 输出: promissReac resolve is success !

附上一张测试截图

1651416055(1).jpg

后续会更新ts版,写的不好,各位看官见谅,有任何不对之处可以直接评论指出,非常感谢!