编辑代码

class MyPromise {
    static PENDING = 'pending'
    static FULFILLED = 'fulfilled'
    static REJECTED = 'rejected'
    constructor(execute) {
        this.status = MyPromise.PENDING  // MyPromise状态
        this.value = null  // 结果
        this.callbacks = []  // 回调函数
        try {
            execute(this.resolve, this.reject)
        } catch (err) {
            this.reject(err)
        }
    }

    resolve(value) {
        if(this.status === MyPromise.PENDING) {  // pending状态修改
            this.value = value  // 保存值
            this.status = MyPromise.FULFILLED  // 修改状态
            setTimeout(() => {
                this.callbacks.forEach(item => {  // 执行回调函数
                    item.onFulfilled(this.value)
                })
            })
        }
    }

    reject(err) {
        if(this.status === MyPromise.PENDING) {
            this.value = err
            this.status = MyPromise.REJECTED
            setTimeout(() => {  // 异步调用 回调函数
                this.callbacks.forEach(item => {
                    item.onRejected(this.value)
                })
            })
        }
    }

    then(onFulfilled, onRejected) {
        if(typeof onFulfilled !== 'function') {
            onFulfilled = (val) => val
        }
        if(typeof onRejected !== 'function') {
            onRejected = (err) => err
        }
        let promise = new MyPromise((resolve, reject) => {
            if(this.status === MyPromise.PENDING) {  // pending 状态
                // 将回调函数存入 callbacks 数组当中
                this.callbacks.push({
                    // 成功回调
                    onFulfilled: (value) => {
                        // parse方法解析判断 循环 promise
                        this.parse(promise, onFulfilled(value), resolve, reject)
                    },
                    onRejected: (err) => {
                        this.parse(promise, onRejected(err), resolve, reject)
                    }
                })
            } else if(this.status === MyPromise.FULFILLED) {
                setTimeout(() => {
                    this.parse(promise, onFulfilled(this.value), resolve, reject)
                })
            } else {
                setTimeout(() => {
                    this.parse(promise, onRejected(this.value), resolve, reject)
                })
            }
        })
        return promise
    }

    parse(promise, result, resolve, reject) {  // 解决循环依赖 并且判断返回值是否是 promise
        if(promise === result) throw new Error("circular promise")
        try {
            // result是执行 onFulfilled / onRejected 函数的返回值
            // 为了实现链式调用 result 的状态决定了返回出来 promise 的状态
            if(result instanceof MyPromise) {  // 返回值也是 promise
                result.then(resolve, reject)  // 
            } else {
                resolve(result)  // 将结果封装成为 promise
            }
        } catch (err) {
            reject(err)
        }
    }

    static resolve(value) {
        return new MyPromise((resolve, reject) => {
            if(value instanceof MyPromise) {
                value.then(resolve, reject)
            } else {
                resolve(value)
            }
        })
    }

    static reject(err) {
        return new MyPromise((resolve, reject) => {
            reject(err)
        })
    }

    static all(promises) {
        return new MyPromise((resolve, reject) => {
            const result = []
            let cnt = 0
            // 存入数组对应位置
            const processData = (i, data, resolve) => {
                result[i] = data
                cnt ++
                if(cnt === promises.length) {
                    resolve(result)
                }
            }
            for(let i = 0; i < promises.length; i ++) {
                promises[i].then((res) => {
                    processData(i, res, resolve)
                }, (err) => {
                    reject(err)
                })
            }
        })
    }

    static race(promises) {
        return new MyPromise((resolve, reject) => {
            for(let p of promises) {
                p.then(resolve, reject)
            }
        })
    }

    catch(onRejected) {
        // 将 onRejected 函数加入到 callbacks
        return this.then(null, onRejected)
    }
}

let p = new Promise((resolve) => {
    resolve(true)
})

// promise
p.then((res) => {
    // result
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve("success")
        }, 1000)
    })
}).then((res) => {
    console.log(res)
})