手写Promise静态方法,详尽注释 (es6)

137 阅读1分钟

Promise.all

手写

// 使用es6新增的全局对象Reflect的静态函数式方法去给Promise构造函数增加'myAll'方法
//用法基本和Object.defindeProperty类似,value对应的就是我们myAll的函数主体
Reflect.defineProperty(Promise, 'myAll', { 
        value: (array) => {
            const results = new Array(); // 创建一个数组接收结果
            let count = 0; // 创建一个计数器,原因在下面阐述
            return new Promise((res, rej) => { // 因为Promise.all返回的也是一个Promise实例,所以要return一个Promise实例
                array.forEach(async (item, index) => { // 遍历数组
                        try {
                            results[index] = await item; 
                            // 把数组中的每一个元素都放到对应index的results中,这里用await并不只是用es6装逼,而是考虑到元素可能不是promise实例,用await可以将普通元素转换为状态是fulfilled的promise再提取PromiseResult,这样就不用分类讨论这个元素的类型是不是promise了。
                        } catch (res) {
                            rej(res) //捕获错误
                        }
                        count++ // 每存入一个元素,计数器就加一
                        if (array.length === count) res(results) // 如果每一个元素都放入了results中,即数组长度和计数器数相等,则返回状态为fulfilled参数为results的promise
                })
            })
        }
    })

测试用例

    const a = new Promise((resolve) => { resolve(1) })
    const b = new Promise((res) => {
        setTimeout(() => { res(2) }, 2000)
    })
    const c = new Promise((res) => {
        setTimeout(() => { res(3) }, 1000)
    })
    function d() {
        return new Promise((res, rej) => { rej('可能是网络的问题,请求失败') })
    }

输出结果

    Promise.myAll([a, b, c, 4, 5, null, undefined]).then((res) => { console.log(res) }).catch((reason) => console.log(reason))
    // [1, 2, 3, 4, 5, null, undefined]
    Promise.myAll([a, b, c, d(), 4, 5, null, undefined]).then((res) => { console.log(res) }).catch((reason) => console.log(reason))
    // 可能是网络的问题,请求失败