编辑代码

/*
    静态方法:
        Promise.resolve 
        Promise.reject 
        Promise.all 
        Promise.race 

    原型方法:
        Promise.prototype.then 
        
        Promise.prototype.finally 返回一个promise,无论结果是 fulfilled 或者是 rejected,都会执行指定的回调函数
            let isLoading = true // 处理加载样式
            request(url)
            .then(res => {  })
            .catch((err) => console.log(err))
            .finally(() => isLoading = false)

        Promise.prototype.catch 
*/


// 定义状态变量
const PENDING = 'PENDGING' // 等待
const FULFILLED = 'FULFILLED' // 成功
const REJECTED = 'REJECTED' // 失败

class MyPromise {
    constructor (executor) {
        // 立即执行,所以 resolve、reject 方法需要使用箭头函数
        // 里面的 this 指向为当前的 promise 对象

        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            this.reject(e)
        }
    }

    status = PENDING // promise 状态

    value = undefined // 成功值

    reason = undefined // 失败值

    successCallback = [] // 成功回调函数

    failCallback = [] // 失败回调函数

    resolve = value => {
        if (this.status !== PENDING) return 

        this.status = FULFILLED

        this.value = value

        // 取出 successCallback  队列里面的成功回调执行
        while (this.successCallback.length) this.successCallback.shift()()
    }

    reject =  reason => {
        if (this.status !== PENDING) return 
    
        this.status = REJECTED

        this.reason = reason

        while (this.failCallback.length) this.failCallback.shift()() 
    }
    
    then (successCallback, failCallback) {
        // 1、返回的也是一个 promise 
        // 2、successCallback 和 failCallback 可以都传也可都不穿,也可只传一个
        // 3、如果都不穿,需要把 promise 传递地给下一个来解决
        // 4、如果只是传递一个,需要创造一个回调函数来占位
        // 5、promise 的每一次链式调用,都会产生一个新的 Promise 对象

        // 如果 then 中 传递了 successCallback,则使用 successCallback,否则构造一个回调函数 
        successCallback = successCallback ? successCallback : value => value
        failCallback = failCallback ? failCallback : reason => { throw reason }

        const promise2 = new MyPromise((resolve, reject) => {
            if (this.status === FULFILLED) {
                // 加入异步任务
                setTimeout(() => {
                    try {
                        const x = successCallback(this.value)

                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            } else if (this.status === REJECTED) {
                setTimeout(() => {
                    try {
                        const x = failCallback(this.reason)

                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            } else { // 异步任务的情况,仍然处于 pending 状态
                this.successCallback.push(() => {
                    setTimeout(() => {
                        try {
                            const x = successCallback(this.value)

                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })

                this.failCallback.push(() => {
                    setTimeout(() => {
                        try {
                            const x = failCallback(this.reason)

                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })
            }
        })

        // promise 的链式调用通过返回一个新的 promise 对象
        return promise2
    }

    finally (callback) {
        return this.then(value => {
            return MyPromise.resolve(callback()).then(() => value)
        }, reason => {
            return MyPromise.resolve(callback()).then(() => { throw reason })
        })
    }

    catch (failCallback) {
        return this.then(undefined, failCallback)
    }

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

    static all (arr) {
        const result = []
        let index = 0

        return new MyPromise((resolve, reject) => {
            function addData (key, value) {
                result[key] = value

                index++

                if (index === arr.length) {
                    resolve(result)
                }
            }

            for (let i = 0; i < arr.length; i++) {
                const current = arr[i]

                if (current instanceof MyPromise) { // promise 对象处理
                    current.then(value => addData(i, value), reason => reject(reason))
                } else { // 普通值处理
                    addData(i, arr[i])
                }
            }
        })
    }

    static race (arr) {
        return new MyPromise((resolve, reject) => {
            for (let i = 0; i < arr.length; i++) {
                const current = arr[i]
                if (current instanceof MyPromise) {
                    current.then(value => {
                         resolve(value)
                    }, reason => {
                         reject(reason)
                    })
                } else {
                     resolve(current)
                }
            }
        })
    }
}

function resolvePromise (promise, x, resolve, reject) {
    if (promise === x) { // 处理循环引用报错
        return reject(new TypeError('chaining cycle detected for promise #<Promise>'))
    }

    if (x instanceof MyPromise) {
        x.then(resolve, reject)
    } else {
        resolve(x)
    }
}

/************************************************************/

const t = function () {
    setTimeout(() => { console.log('定时器执行') }, 1000)
}
const p = function () {
    return new MyPromise((resolve, reject) => {
        console.log('promise 执行器执行')
        resolve('promise resolve 执行')
    })
}

MyPromise.race([t(), p(), 4]).then(r => console.log(r))

Promise.race([t(), p(), 4]).then(r => console.log(r))

console.log(123)