编辑代码

class MyPromise {
    static PENDING = 'PENDING'
    static FULFILLED = 'FULFILLED'
    static REJECTED = 'REJECTED'
    status = MyPromise.PENDING
    callbacks = []
    value = null
    constructor(executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (err) {
            this.reject(err)
        }
    }

    resolve(res) {
        if(this.status === MyPromise.PENDING) {
            this.value = res
            this.status = MyPromise.FULFILLED
            queueMicrotask(() => {
                this.callbacks.forEach(({fulfilled}) => {
                    fulfilled(res)
                })
            })
        }
    }

    reject(err) {
        if(this.status === MyPromise.REJECTED) {
            this.status = MyPromise.REJECTED
            this.value = err
            queueMicrotask(() => {
                this.callbacks.forEach(({rejected}) => {
                    rejected(err)
                })
            })
        }
    }

    then(fulfilled, rejected) {
        if(typeof fulfilled !== 'function') fulfilled = (res) => res
        if(typeof rejected !== 'function') rejected = (err) => err
        
        const promise = new MyPromise((resolve, reject) => {
            if(this.status === MyPromise.PENDING) {
                this.callbacks.push({
                    fulfilled: (res) => this.parse(promise, fulfilled(res), resolve, reject),
                    rejected: (err) => this.parse(promise, rejected, resolve, reject)
                })
            } else if(this.status === MyPromise.FULFILLED) {
                queueMicrotask(() => {
                    this.parse(promise, fulfilled(this.value), resolve, reject)
                })
            } else {
                queueMicrotask(() => {
                    this.parse(promise, rejected(this.value), resolve, reject)
                })
            }
        })
        return promise
    }

    parse(promise, result, resolve, reject) {
        if(promise === result) throw new Error('circular promise')
        try {
            if(result instanceof MyPromise) {
                result.then(resolve, reject)
            } else {
                resolve(result)
            }
        } catch (err) {
            reject(err)
        }
    }
}