SOURCE

function myPromise (excutor) {
    const PENDING = 'pending'
    const FULFILLED = 'fulfilled'
    const REJECTED = 'rejected'
    const self = this
    self.status = PENDING
    self.value = undefined;
    self.reason = undefined
    var onResolvedTOdoList = []
    var onRejectedTOdoList = []

    resolve = (value) => {
        if (self.status != PENDING) return
        setTimeout(() => {
            self.value = value
            self.status = FULFILLED
            onResolvedTOdoList.forEach((cb) => {
                cb(value)
            })
        }, 0)
    }
    reject = (reason) => {
        if (self.status != PENDING) return
        setTimeout(() => {
            self.reason = reason
            self.status = REJECTED
            onRejectedTOdoList.forEach((cb) => {
                cb(reason)
            })
        }, 0)
    }
    try {
        excutor(resolve, reject)
    } catch (e) {
        self.reject(e)
    }
}
myPromise.prototype.myThen = function (onResolved, onRejected) {
    onResolved = typeof onResolved === "function" ? onResolved : (value) => value;
    onRejected = typeof onRejected === 'function' ? onRejected : (err) => {throw err}
    const _self = this
    const callPromise = new myPromise((resolve, reject) => {
        function resolvePromise (callPromise, x, resolve, reject) {
            if (callPromise === x) {
                reject(new TypeError('The promise is the same as the return value'))
            }
            if (x instanceof myPromise) {
                if (x.status === PENDING) {
                    x.then((y) => {
                        resolvePromise(callPromise, y, resolve, reject)
                    }, (error) => {
                        reject(error)
                    })
                } else {
                    x.then(resolve, reject)
                }
            } else {
                resolve(x)
            }
            return callPromise
        }
        const fulfilledMicrotask = () => {
            queueMicrotask(() => {
                try {
                    // 回调值
                    const x = onResolved(_self.value)
                    // 状态透传
                    resolvePromise(callPromise, x, resolve, reject)
                } catch (e) {
                    reject(e)
                }
            })
        }
        const rejectedMicrotask = () => {
            queueMicrotask(() => {
                try {
                    const x = onRejected(_self.reason)
                    resolvePromise(callPromise, x, resolve, reject)
                } catch (e) {
                    reject(e)
                }
            })
        }
        // pending 态保证延迟回调
        if (_self.status === PENDING) {
            _self.onResolvedTOdoList.push(fulfilledMicrotask)
            _self.onRejectedTOdoList.push(rejectedMicrotask)
        } else if (_self.status === FULFILLED) {
            fulfilledMicrotask()
        } else {
            rejectedMicrotask()
        }
    })
    return callPromise
}
// 判断参数
myPromise.prototype.myResolve = function (pm) {
    // 如果 pm 是一个 promsie 实例
    if (pm instanceof myPromise) return pm
    // 如果 pm 有 then 方法,并且是一个函数,则调用
    // 否则就返回成功态的 promise
    return new myPromise((resolve, reject) => {
        if (pm && pm.then && typeof pm.then == 'function') {
            pm.then(resolve, reject)
        } else {
            resolve(pm)
        }
    })
}

// 返回失败态的 promise
myPromise.prototype.myReject = function (reason) {
    return new myPromise((resolve, reject) => {
        reject(reason)
    })
}

// 不管 promise 状态都会执行,并且不影响 promise 链过程中的值透传
myPromise.prototype.myFinally = function (cb) {
    this.then((value) => {
        return myPromise.myResolve(callback()).then(() => {
            return value
        })
    }, (error) => {
        return myPromise.myResolve(callback()).then(() => {
            throw error
        })
    })
}

//
myPromise.prototype.myAll = function (promises) {
    promises = [...promises]
    return new Promise((resolve, reject) => {
        const res = []
        const len = promises.length
        if (len == 0) {
            resolve(res)
            return
        }
        const handleData = (idx, data) => {
            res[i] = data
            if (idx == len - 1) {
                resolve(res)
            }
        }
        for (let i = 0; i < promises.length; i++) {
            myPromise.myResolve(promises[i]).then((data) => {
                handleData(i, data)
            }).catch((err) => {
                reject(err)
            })
        }
    })
}

myPromise.prototype.myRace = function (promises) {
    promises = [...promises]
    return new myPromise((resolve, reject) => {
        const len = promises.length
        if (len === 0) {
            resolve()
        }
        for (let i = 0; i < promises.length; i++) {
            myPromise.myResolve(promises[i]).then((res) => {
                resolve(res)
            }).catch((err) => {
                reject(err)
            })
        }        
    })
}

function mySetinterval (cb, wait) {
    let timer = null
    function inner () {
        timer = setTimeout(() => {
            cb()
            clearTimeout(timer)
            inner()
        }, wait)
    }
    inner()
}
console 命令行工具 X clear

                    
>
console