Promise.all = function (arr) {
// 实现代码
};
1) 核心思路
2)实现代码
一般来说,Promise.all 用来处理多个并发请求,也是为了页面数据构造的方便,将一个页面所用到的在不同接口的数据一起请求过来,不过,如果其中一个接口失败了,多个请求也就失败了,页面可能啥也出不来,这就看当前页面的耦合程度了~
function promiseAll(promises) {
return new Promise(function(resolve, reject) {
if(!Array.isArray(promises)){
throw new TypeError(`argument must be a array`)
}
var resolvedCounter = 0;
var promiseNum = promises.length;
var resolvedResult = [];
for (let i = 0; i < promiseNum; i++) {
Promise.resolve(promises[i]).then(value=>{
resolvedCounter++;
resolvedResult[i] = value;
if (resolvedCounter == promiseNum) {
return resolve(resolvedResult)
}
},error=>{
return reject(error)
})
}
})
}
// test
let p1 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(1)
}, 1000)
})
let p2 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(2)
}, 2000)
})
let p3 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(3)
}, 3000)
})
promiseAll([p3, p1, p2]).then(res => {
console.log(res) // [3, 1, 2]
})
/**
* Promise.all
* @description 当这个数组里的所有promise对象全部变为resolve状态的时候,才会resolve, 当有一个promise对象变为reject状态时,就不再执行直接 reject
* @param {*} values promise对象组成的数组作为参数
*/
Promise.prototype.all = (values)=>{
return new Promise((resolve,reject)=>{
let resultArr = []
let count = 0
let resultByKey = (value,index)=>{
resultArr[index] = value
if(++count === values.length){
resolve(resultArr)
}
}
values.forEach((promise,index)=>{
promise.then((value)=>{
resultByKey(value,index)
},reject)
})
})
}
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
throw new Error('argument must be a array');
}
// 用来记录Promise成功的次数
let resolveCount = 0,
// 用来保存Promise成功的结果
resolveDataList = [];
for (let index = 0, len = promises.length; index < len; index++) {
const p = promises[index];
Promise.resolve(p).then(data => {
resolveDataList[index] = data;
// promise成功次数等于promises数组长度,则成功
if (++resolveCount === len) {
resolve(resolveDataList);
}
// 有一个失败就失败
}, reject);
}
});
}
Promise.race = (promises = []) => {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
throw new TypeError(`argument must be a array`);
}
for (const p of promises) {
// 有一个成功就返回成功状态的promise
// 有一个失败就返回失败状态的promise
p.then(resolve, reject);
}
});
}
// Promise.finally() 最终的,无论如何finally中传递的回调函数 必须会执行,如果返回一个promise,会等待这个Promise执行完成
Promise.prototype.finally = function(callback){
return this.then(res => {
// 如果then方法返回一个Promise, 就会等待这个方法执行完毕,所以需要包装成Promise才能等待
return Promise.resolve(callback()).then(() => res);
}, err => {
return Promise.resolve(callback()).then(() => {
throw err;
})
});
}
let p1 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(1)
}, 1000)
})
let p2 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(2)
}, 2000)
})
let p3 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(3)
}, 3000)
})
Promise.all([p3, p1, p2]).then(res => {
console.log(res) // [3, 1, 2]
});
Promise.myAll = function (arr) {
const length = arr.length;
let result = new Array(length);
let count = 0;
let succeedCount = 0;
let resolveAllFn = null;
let rejectAllFn = null;
let someErr = null;
function addcount() {
count++;
if (count === length) {
succeedCount === length
? resolveAllFn(result)
: rejectAllFn(someErr)
}
}
for (const [i, p] of arr.entries()) {
Promise.resolve(p).then((res) => {
result[i] = res;
succeedCount++;
addcount();
}, (err) => {
someErr = err;
addcount();
})
}
return new Promise((rs, rj) => {
resolveAllFn = rs;
rejectAllFn = rj;
})
}
Promise.myAll([
new Promise(rs=>{
setTimeout(() => {
rs(0)
}, 1000);
}),
Promise.resolve(1),
]).then((res) => {
console.log(res);//[ 0, 1]
});
Promise.myAll([
new Promise((_, rj)=>{
setTimeout(() => {
rj(0)
}, 1000);
}),
Promise.resolve(1),
]).then(() => {},err=>{
console.log(err); //0
});
Promise.all = (...promises) => {
const results = [];
const merged = promises.reduce(
(acc, p) => acc.then(() => p).then(r => results.push(r)),
Promise.resolve(null));
return merged.then(() => results);
};
from: https://eddmann.com/posts/implementing-promise-all-and-promise-race-in-javascript/
Promise.all = async (promises) => {
const results = [];
for (promise of promises) {
results.push(await promise);
}
return results;
};
Most helpful comment