手写Promise

76 阅读2分钟

手写Promise

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
//新建一个MyPromise类
class MyPromise {

    constructor(executor) {
        //executor是一个执行器,会立马执行
        try {
            executor(this.resolve, this.reject)
        } catch (error) {
            this.reject(error)
        }
    }

    status = PENDING
    //成功或者失败函数传的参数
    value = null
    reason = null
    //如果promise里面是异步函数,则需要暂存then的回调,等待异步执行完了之后再调用then回调
    onFulfilledCallback = []
    onRejectedCallback = []

    //改变状态的函数
    resolve = (value) => {
        //为了保证状态只能变化一次
        if (this.status === PENDING) {
            this.status = FULFILLED
            this.value = value
            //判断成功回调是否存在,如果岑在就调用回调函数
            while (this.onFulfilledCallback.length) {
                this.onFulfilledCallback.shift()(value)
            }
        }
    }

    //改变状态的函数
    reject = (reason) => {
        if (this.status === PENDING) {
            this.status = REJECTED
            this.reason = reason
            //判断失败回调是否存在,如果岑在就调用回调函数
            while (this.onRejectedCallback.length) {
                this.onRejectedCallback.shift()(reason)
            }
        }
    }

    //then回调
    then(onFulfilled, onRejected) {
        // 判断是否传递了成功和失败的回调函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }


        //创建return的promise实例
        const promise2 = new MyPromise((resolve, reject) => {

            //如果then方法立马执行,状态为成功
            if (this.status === FULFILLED) {
                // 需要创建成微任务,因为不能在promise2初始化完成之前调用promise2
                queueMicrotask(() => {
                    try {
                        //获取回调函数的返回值,前一个then需要有返回值
                        const x = onFulfilled(this.value)
                        //进行处理,处理其状态
                        resolvePromise2(promise2, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })

            } else if (this.status === REJECTED) {
                //如果then方法立马执行,状态为失败
                queueMicrotask(() => {
                    try {
                        const x = onRejected(this.reason)
                        resolvePromise2(promise2, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })

            } else if (this.status === PENDING) {
                //如果promise里面是异步函数,则需要暂存then的回调,等待异步执行完了之后再调用then回调
                this.onFulfilledCallback.push(() => {
                    queueMicrotask(() => {
                        try {
                            const x = onFulfilled(this.value)
                            resolvePromise2(promise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                    })
                })
                this.onRejectedCallback.push(() => {
                    queueMicrotask(() => {
                        try {
                            const x = onRejected(this.value)
                            resolvePromise2(promise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                    })
                })
            }
        })
        //为了实现then的链式调用
        return promise2
    }

    // 支持MyPromise.resolve(value)这样的方法创建一个成功的promise对象
    static resolve(parameter) {
        // 如果传入的是 MyPromise,就直接返回
        if (parameter instanceof MyPromise) {
            return parameter
        }

        // 转成常规方法
        return new MyPromise(resolve => {
            resolve(parameter)
        })
    }
    static reject(reason) {
        return new MyPromise((resolve, reject) => {
            reject(reason)
        })
    }

}

function resolvePromise2(promise2, x, resolve, reject) {
    // 防止then里面的函数返回的promise和then方法要返回的promise是同一个
    if (promise2 === x) {
        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }

    if (x instanceof MyPromise) {
        //? x.then是为了将其状态变为fulfilled或者rejected
        x.then(resolve, reject)
    } else {
        resolve(x)
    }
}

module.exports = MyPromise

测试用例

const MyPromise = require('./MyPromise')
const p1 = new MyPromise((resolve, reject) => {
    //实现异步逻辑
    // setTimeout(() => {
    //     resolve('success')
    // }, 1000);
    resolve('success111')
    // throw new Error('执行器错误')
})

// 实现then方法的多次调用
p1.then().then().then(value => { console.log(value); })

console.log(...[1, 2, 3, [4, 5, [6, 7]]]);
console.log([1, 2, 3].entries());