手写promise.all

一、手写promise.all

先总结下promise.all用法的特点:

  1. 接收一个 Promise 实例的数组或具有 Iterator 接口的对象,
  2. 如果元素不是 Promise 对象,则使用 Promise.resolve 转成 Promise 对象
  3. 如果全部成功,状态变为 resolved,返回值将组成一个数组传给回调
  4. 只要有一个失败,状态就变为 rejected,返回值将直接传递给回调all() 的返回值也是新的 Promise 对象
1. 具体代码

代码逻辑:

  1. 判断传入形参是否合法,非法形参直接返回空集合。
  2. 定义用于记录执行次数的变量和返回结果集。
  3. 循环遍历执行
    3.1 考虑可能是普通对象,使用 Promise.resolve对单次循环对象进行封装处理。
    3.2 将每次执行结果放入定义的结果集中。
    3.3 自加记录执行数 等于 循环次数,返回结果集
    3.4 任何一个Promise对象执行失败,则调用reject()方法

es5写法:

Promise.all1 = function(iterators) {
    return new Promise((resolve, reject) => {
        if (!iterators || iterators.length === 0) {
            resolve([])
        } else {
            // 计算器,用于判断所有任务是否执行完成
            var count = 0;
            // 结果数组
            var result = [];
            // 执行数组长度
            var len = iterators.length

            for(var i = 0; i < len; i++) {
                // 利用IIFE来完成变量i的锁定
                (function(i) {
                    // 考虑到iterators[i]可能是普通对象,则统一包装为Promise对象
                    Promise.resolve(iterators[i]).then( (data) => {
                        // 按顺序保存对应的结果
                        result[i] = data;
                        // 判断++count 的次数是否等于 传入执行数组的长度
                        if (++count === len) {
                            resolve(result);
                        }
                    }, (err) => {
                        // 任何一个Promise对象执行失败,则调用reject()方法
                        reject(err);
                    })
                })(i)
            }
        }
    })
}

es6写法:

Promise.all2 = function(iterators) {
    return new Promise((resolve, reject) => {
        if (!iterators || iterators.length === 0) {
            resolve([])
        } else {
            // 计算器,用于判断所有任务是否执行完成
            let count = 0;
            // 结果数组
            let result = [];
            // 执行数组长度
            let len = iterators.length
            for(let i = 0; i < len; i++) {
                // 考虑到iterators[i]可能是普通对象,则统一包装为Promise对象
                Promise.resolve(iterators[i]).then( (data) => {
                    // 按顺序保存对应的结果
                    result[i] = data;
                    // 判断++count 的次数是否等于 传入执行数组的长度
                    if (++count === len) {
                        resolve(result);
                    }
                }, (err) => {
                    // 任何一个Promise对象执行失败,则调用reject()方法
                    reject(err);
                })
            }
        }
    })
}

测试代码:

const f1 = new Promise( (resolve,reject) => {
    console.log('enter f1')
    resolve('f1')
})

const f2 = new Promise( (resolve,reject) => {
    console.log('enter f2')
    reject('err')
})
const f3 = new Promise( (resolve,reject) => {
    console.log('enter f3')
    resolve('f3')
})

Promise.all2([f1, f2, f3]).then( data => {
    console.log(data)
}).catch(err => {
    console.log(err)
})

其他参看:ECMAScript-异步编程-Promise

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值