5、promise.all
首先promise.all的作用:
all主要用来解决多个异步操作的调用问题,类似于Promise.all的功能。
function p1 (){
return new Promise((resolve , reject) => {
setTimeout(() => {
resolve('p1 resolved');
}, 1000);
})
}
function p2 (){
return new Promise((resolve , reject) => {
resolve('p2 resolved');
})
}
Promise.all([p1(), p2()]).then((results) => {
console.log(results); // ['p1 resolved', 'p2 resolved']
}).catch((error) => {
console.error(error);
});
因为p1是有setTimeout的,所以p1会在1秒后执行,而p2是立即执行的,所以p1和p2的结果会在1秒后一起输出。但是我们使用了 Promise.all,所以它会等待所有的 Promise 都完成后再执行 then 方法。这就是为什么结果是 ['p1 resolved', 'p2 resolved'],而不是 ['p2 resolved', 'p1 resolved']。
开始手写:
-
all方法是静态方法,所以不需要实例化
-
all方法的返回值是一个新的promise对象,这个新的promise对象的结果是一个数组,数组的长度和传入的数组长度一致
-
如果有一个失败,就直接reject
-
如果所有的都成功,就resolve一个数组,数组的长度和传入的数组长度一致
-
for循环一下子就执行完了,但是有异步执行的操作,我们要设一个计数器,当数组的长度和传入的数组长度一致的时候,就要reject
static all(array){ let res = []; //存放结果的数组 let count = 0; // 计数器 return new Commitment((resolve , reject) => { // 添加数据的函数 function addData (key , value){ res[key] = value; count++; // 每添加一个数据就加1 // 如果计数器等于数组长度,就说明所有数据都添加完了 if(count === array.length){ // 说明所有数据都添加完了,就resolve resolve(res);//保证所有数据都添加完了才resolve,因为for循环一下子就执行完了,但是有异步执行的操作 } } // 循环 for(let i = 0 ; i < array.length ; i++){ let cur = array[i]; // 判断是否是普通值 if(cur instanceof Commitment){ // 如果不是,执行promise,注意如果有一个失败,就直接reject cur.then((value) => addData(i , value) , (error) => reject(error)); }else { // 如果是,直接添加到结果数组中 addData(i , cur); } } }) }
总结一下:promise.all方法主要是处理多个异步的调用问题,传入一个数组,返回的是新的promise对象,它是静态方式。所以传入数组后我们循环遍历了这个数组,如果它是普通值,如果是就要直接添加到结果数组里卖弄,如果不是,then等待结果,只要有一个错误,那么就直接reject,最后当结果数组的长度和传入数组的长度相同的时候就要resolve啦~~