SOURCE

/**
 * 实现promise,class 定义对象属性方法
 * construct(fn)构造函数,初始化属性,promiseResult返回值,执行传入函数
 * 初始状态为pending
 * fn函数,接受两个回调函数作为参数resolve,reject
 * 绑定resolve,reject,指向当前myPromise resolve.bind(this)
 * 执行resolve,状态更改为 fulfilled
 * 执行reject,状态更改为rejected
 * 状态由pending更改后,不可二次更改
 * 抛出异常,状态更改为rejected
 * 实现then方法
 * then(onFulfilled,onRejected),接受两个回调函数作为参数
 * 当状态为fulfilled,执行第一个回调,参数为promiseResult
 * 当状态为rejected,执行第二个回调,参数为promiseResult
 * 实现定时器调用
 * 当状态为pending,暂存回调函数onFulfilled,进入数组
 * 当执行完resolve()或reject()方法,取出最先存入数组的回调函数执行
 * 实现链式调用
 * then()返回一个promise对象
 * 新对象的执行受上一个then()返回结果影响 result= callback(this.promiseResult)
 * 判断返回值是否是promise对象  result instanceof MyPromise
 * 判断返回是否成功 result.then()
 * 返回成功,新promise返回成功
 * 返回失败,新promise返回失败
 * 抛出异常,返回失败
 */


class MyPromise {
    //构造函数
    constructor(fn) {
        this.initValue()
        this.initBind()

        try {
            // 执行传入的函数 
            fn(this.resolve, this.reject)
        } catch (err) {
            // 捕获异常,设置rejected状态
            this.reject(err)
        }

    }

    initValue() {
        // 定义初始状态
        this.promiseState = 'pending'
        // 定义初始返回值
        this.promiseResult = null
        this.onFulfilledCallback = []  // 成功回调数组
        this.onRejectedCallback = [] // 失败回调数组
    }

    // 绑定resolve  reject 指向当前 MyPromise
    initBind() {
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }

    // 定义resolve方法
    resolve(value) {
        // 状态不可二次更改
        if (this.promiseState !== 'pending') return
        this.promiseState = 'fulfilled'
        this.promiseResult = value
        // 当前回调数组内存在未执行回调
        while (this.onFulfilledCallback.length > 0) {
            // 取出数组头部回调函数并执行
            this.onFulfilledCallback.shift()(value)
        }

    }
    // 定义reject方法
    reject(reason) {
        // 状态不可二次更改
        if (this.promiseState !== 'pending') return
        this.promiseState = 'rejected'
        this.promiseResult = reason
        // 当前回调数组内存在未执行回调
        while (this.onRejectedCallback.length > 0) {
            // 取出数组头部回调函数并执行
            this.onRejectedCallback.shift()(reason)
        }
    }
    /**
     * then接受两个回调,一个成功回调,一个失败回调
     * 当promise状态为fuldilled,执行成功回调,为rejected执行失败回调
     * 如resolve或reject在定时器中,当定时器结束,在执行then()
     * then支持链式调用,下一次then执行受上一次then返回值的影响
     */

    // 接受两个回调参数
    then(onFulfilled, onRejected) {
        // 校验参数是否是函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : onFulfilled => onFulfilled
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

        const thenPromise = new MyPromise((resolve, reject) => {
            const resolvePromise = cb => {
                setTimeout(() => {
                    try {
                        // 执行then方法参数的回调函数
                        const result = cb(this.promiseResult)
                        if (result === thenPromise) {
                            throw ('Can not return self')
                        } else if (result instanceof MyPromise) {
                            result.then(resolve, reject)
                        } else {
                            resolve(result)
                        }
                    } catch (err) {
                        reject(err)
                    }
                })
            }
            if (this.promiseState === 'fulfilled') {
                resolvePromise(onFulfilled)
            } else if (this.promiseState === 'rejected') {
                resolvePromise(onFulfilled)
            } else if (this.promiseState === 'pending') {
                // 存储回调函数,并绑定当前this
                this.onFulfilledCallback.push(resolvePromise.bind(this, onFulfilled))
                this.onRejectedCallback.push(resolvePromise.bind(this, onRejected))
            }
        })
        return thenPromise
    }

    /**
     * 2.all 方法 是否有链式调用 可以 返回新promise
     * 3.promise项如何确认执行完成  promise.then()
     */

    static all(promises) {
        const result = []
        let count = 0

        return new MyPromise((resolve, reject) => {

            const addData = function (item, index) {
                result[index] = item
                count++
                if (count === promises.length) {
                    resolve(result)
                }
            }
            promises.forEach((item, index) => {
                if (item instanceof MyPromise) {
                    item.then(res => {
                        addData(res,index)
                    },err=>{
                        reject(err)
                    })

                } else {
                    addData(item,index)
                }
            })
        })
    }
}

const test1 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(1)
    }, 5000)
})

const test2 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(2)
    }, 3000)
})

const test3 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(3)
    }, 2000)
})

const res = MyPromise.all([test1, test2, test3]).then(res=>console.log(res))



console 命令行工具 X clear

                    
>
console