我相信有些同窗在面试的过程当中,面试官会问你可否简单描述一下
Promise.all
的原理,小编我也是被问到,因而也在网上找了几遍文章和例子,看完以后也是死恍然大悟,但愿能帮到小伙伴们git
Promise.all 接收一个 promise 对象的数组做为参数,当这个数组里的全部 promise 对象所有变为resolve或 有 reject 状态出现的时候,它才会去调用 .then 方法,它们是并发执行的github
一、Promise.all()方法将多个Promise实例包装成一个Promise对象(p),接受一个数组(p1,p2,p3)做为参数,数组中不必定须要都是Promise对象,可是必定具备Iterator接口,若是不是的话,就会调用Promise.resolve将其转化为Promise对象以后再进行处理。面试
二、使用Promise.all()生成的Promise对象(p)的状态是由数组中的Promise对象(p1,p2,p3)决定的;数组
Promise.all()方法生成的Promise对象也会有一个catch方法来捕获错误处理,可是若是数组中的Promise对象变成rejected状态时,而且这个对象还定义了catch的方法,那么rejected的对象会执行本身的catch方法,而且返回一个状态为fullfilled的Promise对象,Promise.all()生成的对象会接受这个Promise对象,不会返回rejected状态promise
function PromiseAll(arr) { //PromiseAll的返回值为一个promise对象 return new Promise((resolve, reject) => { //PromiseAll的入参必须是数组 if (!Array.isArray(arr)) { return reject(new TypeError('arr must be an array.')); } let resArr = []; for (let i in arr) { (function(i) { Promise.resolve(arr[i]).then(res => { resArr.push(res); //只有全部的都成功了,才会返回resolve if (i == arr.length - 1) { return resolve(resArr); } }, err => { // 只要出错就抛出 return reject(err) }).catch(err => { console.log(err) }) })(i) } }) } //测试 const pro1 = new Promise((res,rej) => { setTimeout(() => { res('1') },1000) }) const pro2 = new Promise((res,rej) => { setTimeout(() => { res('2') },2000) }) const pro3 = new Promise((res,rej) => { setTimeout(() => { res('3') },3000) }) const proAll = PromiseAll([pro1,pro2,pro3]) .then(res => console.log(res) // 3秒以后打印 ["1", "2", "3"] ) .catch((e) => { console.log(e) }) 复制代码
function PromiseAll(promiseArrs) { return new Promise((resolve, reject) => { //返回一个新的Promise let arr = []; //定义一个空数组存放结果 let i = 0; function handleData(index, data) { //处理数据函数 arr[index] = data; i++; if (i === promiseArrs.length) { //当i等于传递的数组的长度时 resolve(arr); //执行resolve,并将结果放入 } } for (let i = 0; i < promiseArrs.length; i++) { //循环遍历数组 promiseArrs[i].then((data) => { handleData(i, data); //将结果和索引传入handleData函数 }, reject) } }) } // 测试 const pro1 = new Promise((res,rej) => { setTimeout(() => { res('1') },1000) }) const pro2 = new Promise((res,rej) => { setTimeout(() => { res('2') },2000) }) const pro3 = new Promise((res,rej) => { setTimeout(() => { res('3') },3000) }) const proAll = PromiseAll([pro1,pro2,pro3]) .then(res => console.log(res) // 3秒以后打印 ["1", "2", "3"] ) .catch((e) => { console.log(e) }) 复制代码
function PromiseAll(promiseArray) { return new Promise(function(resolve,reject){ //判断参数类型 if(!Array.isArray(promiseArray)){ return reject(new TypeError('arguments muse be an array')) } var counter = 0, promiseNum = promiseArray.length, resolvedArray = new Array(promiseNum); for(var i = 0; i < promiseNum; i++){ (function(i){ Promise.resolve(promiseArray[i]).then(function(value){ counter++; resolvedArray[i] = value; if(counter == promiseNum){ return resolve(resolvedArray) } },function(reason){ return reject(reason) }) })(i) } }) } // 测试 const pro1 = new Promise((res,rej) => { setTimeout(() => { res('1') },1000) }) const pro2 = new Promise((res,rej) => { setTimeout(() => { res('2') },2000) }) const pro3 = new Promise((res,rej) => { setTimeout(() => { res('3') },3000) }) const proAll = PromiseAll([pro1,pro2,pro3]) .then(res => console.log(res) // 3秒以后打印 ["1", "2", "3"] ) .catch((e) => { console.log(e) }) 复制代码
无论版本如何变更,只要围绕Promise.all几个特色解读就能够markdown
介绍下 Promise.all 使用、原理实现及错误处理
手动实现一个 Promise.all()
实现promise.all方法
并发