最近面试老是被问到这个,所以记录一下
Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
demo:
let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})
let p2 = new Promise((resolve, reject) => {
resolve('success')
})
let p3 = Promse.reject('失败')
Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})
Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})
如何自己实现一个promise.all呢
1、如果传参对象为空
function myPromiseAll(arr) {
// 定义一个数组
let result = [];
return new Promise((resolve, reject) => {
// 现在只考虑 “在完成情况下” ,会返回一个数组
resolve(result);
});
}
let pResult = myPromiseAll([]);
pResult.then(value=>{
console.log(pResult); // 输出 Promise { <state>: "fulfilled", <value>: [] }
console.log(value); // 输出:[]
})
2、如果传参对象不是promise
function myPromiseAll(arr) {
let result = [];
return new Promise((resolve, reject) => {
for(let i = 0; i < arr.length; i++) {
result.push(arr[i]);
}
resolve(result);
});
}
let pResult = myPromiseAll([1,2,3]); // 元素不是Promise实例
pResult.then(value=>{
console.log(pResult); // 输出: Promise { <state>: "fulfilled", <value>: (3) […] }
console.log(value); // 输出: Array(3) [ 1, 2, 3 ]
})
3、综合所有情况
function myPromiseAll(arr) {
let result = [];
return new Promise((resolve, reject) => {
// 数组为空,直接resolve了
if(arr.length == 0) {
resolve(result);
}
for(let i = 0; i < arr.length; i++) {
if(arr[i].then) { // 若元素是Promise实例,则会有then函数,这里只是简单的作为判断标准
// 元素是Promise
arr[i].then(value => {
console.log(value);
result[i] = value;
// 想一想什么时候resolve呢?--- 所有Promise实例都完成了
if(result.length == arr.length) {
console.log("所有都完成了")
resolve(result);
}
})
} else {
result.push(arr[i]);
// 这段代码跟上面重复,想想,能不能提取放到外面,会出现什么情况呢?
if(result.length == arr.length) {
resolve(result);
}
}
}
});
}
let p1 = new Promise((resolve, reject)=> {
setTimeout(resolve, 2000, "P1 resolved");
})
let p2 = new Promise((resolve, reject)=> {
setTimeout(resolve, 3000, "P2 resolved");
})
let p3 = new Promise((resolve, reject)=> {
setTimeout(resolve, 4000, "P3 resolved");
})
let pResult = myPromiseAll([p1,p2,p3]);
pResult.then(value=>{
console.log(pResult);
console.log(value);
})
// 输出
// P1 resolved
// P2 resolved
// P3 resolved
// 所有都完成了
// Promise { <state>: "fulfilled", <value>: (3) […] }
// Array(3) [ "P1 resolved", "P2 resolved", "P3 resolved" ]
4、如何传入的promise中有失败的呢?
function myPromiseAll(arr) {
let result = [];
return new Promise((resolve, reject) => {
// 如果数组为空,直接返回空数组
if(arr.length == 0) {
resolve(result);
}
for(let i = 0; i < arr.length; i++) {
if(arr[i].then) { // 若元素是Promise实例,则会有then函数,这里只是简单的作为判断标准
// 元素是Promise
arr[i].then(value => {
console.log(value);
result.push(value);
// 想一想什么时候resolve呢?
if(result.length == arr.length) {
console.log("所有都成功了")
resolve(result);
}
}, err => {
console.log("很不幸,其中一个失败了");
// 注意到没, 这里没有像上面的判断 result.length == arr.length, 为什么?
// 只要碰到 resolve 或 reject ,就结束了
reject(err);
})
} else {
result.push(arr[i]);
// 这段代码跟上面重复,想想,能不能提取放到外面,会出现什么情况呢?
if(result.length == arr.length) {
resolve(result);
}
}
}
});
}
let p1 = new Promise((resolve, reject)=> {
setTimeout(reject, 2000, "P1 rejected");
})
let p2 = new Promise((resolve, reject)=> {
setTimeout(resolve, 3000, "P2 resolved");
})
let p3 = new Promise((resolve, reject)=> {
setTimeout(resolve, 4000, "P3 resolved");
})
let pResult = myPromiseAll([p1,p2,p3]);
pResult.then(value=>{
console.log(pResult); // 是输出成功
console.log(value);
}, err => {
console.log(pResult); // 还是输出失败呢?
console.log(err);
})
// 输出
// 很不幸,其中一个失败了
// Promise { <state>: "rejected" }
// P1 rejected
// P2 resolved
// P3 resolved
Promise.prototype.all = function(promises) {
let results = [];
let promiseCount = 0;
let promisesLength = promises.length;
return new Promise(function(resolve, reject) {
for (let val of promises) {
Promise.resolve(val).then(function(res) {
promiseCount++;
// results.push(res);
results[i] = res;
// 当所有函数都正确执行了,resolve输出所有返回结果。
if (promiseCount === promisesLength) {
return resolve(results);
}
}, function(err) {
return reject(err);
});
}
});
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。


