SOURCE

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

const isFunction = obj => typeof obj === 'function'
const isPromise = obj => obj instanceof Promise

function Promise(f) {
    this.state = PENDING
    this.result = null
    this.callbacks = []

    const onFulfilled = value => {
        transition(this, FULFILLED, value)
    }
    const onRejected = reason => {
        transition(this, REJECTED, reason)
    }

    const resolve = value => {
        resolvePromise(this, value, onFulfilled, onRejected)
        // onFulfilled(value)
    }
    const reject = reason => {
        onRejected(reason)
    }

    try {
        f(resolve, reject)
    } catch (error) {
        reject(error)
    }
}

const resolvePromise = (promise, result, onFulfilled, onRejected) => {
    if (promise === result) {
        return onRejected(new TypeError("禁止套娃"))
    }
    if (isPromise(result)) {
        return result.then(onFulfilled, onRejected)
    }
    onFulfilled(result)
    
}

const transition = (promise, state, result) => {
    if (promise.state !== PENDING) {
        return
    }
    promise.state = state
    promise.result = result
    setTimeout(() => {
        clearCallbacks(promise.callbacks, state, result)
    }, 0);
}
const clearCallbacks = (callbacks, state, result) => {
    while (callbacks.length) {
        handleCallback(callbacks.shift(), state, result)
    }
}

Promise.prototype.then = function (onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
        try {
            const callback = { onFulfilled, onRejected, resolve, reject }
            if (this.state === PENDING) {
                this.callbacks.push(callback)
            } else {
                setTimeout(() => {
                    handleCallback(callback, this.state, this.result)
                }, 0);
            }
        } catch (error) {
            reject(error)
        }
    })
}

const handleCallback = (callback, state, result) => {
    const { onFulfilled, onRejected, resolve, reject } = callback
    if (state === FULFILLED) {
        isFunction(onFulfilled) ? resolve(onFulfilled(result)) : resolve(result)
    } else if (state === REJECTED) {
        isFunction(onRejected) ? resolve(onRejected(result)) : reject(result)
    }
}

Promise.prototype.catch = function (onRejected) {
    return this.then(null, onRejected)
}
Promise.resolve = value => new Promise(resolve => resolve(value))
Promise.reject =  reason => new Promise((_, reject) => reject(reason))

Promise.all = function (promises) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(promises)) {
            return reject(new TypeError('请传入数组'))
        }
        const res = []
        let count = 0;
        promises.forEach((p, index) => {
            Promise.resolve(p).then(data => {
                res[index] = data
                count++
                if (count === promises.length) {
                    resolve(res)
                }
            }).catch((err) => {
                reject(err)
            })
        })
    })
}

Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        promises.forEach(p => {
            p.then(data => {
                resolve(data)
            }).catch((err) => {
                reject(err)
            })
        })
    })
}

const p1 = new Promise((r) => {
    setTimeout(() => {
        r(1)
    }, 100);
})
const p2 = new Promise((r) => {
    setTimeout(() => {
        r(2)
    }, 300);
})
const p3 = new Promise((r) => {
    setTimeout(() => {
        r(3)
    }, 200);
})
const p4 = new Promise((_, r) => {
    setTimeout(() => {
        r(4)
    }, 10);
})

Promise.race([p1, p2, p3, p4]).then((res) => {
    console.log(res);
}).catch(console.log)
console 命令行工具 X clear

                    
>
console