这里主要考察对promise相关api的理解。下面我们来模拟回答和扩展考察面试人员
面试同学回答:
可以使用Promise的Promise.all
和Promise.allSettled
api。在成功的情况下他们返回结果的顺序都是按传入迭代器的顺序输出。
不过两者有些区别:Promise.all
如果遇到拒绝的Promise,只返回拒绝的内容,而Promise.allSettled
不管兑现还是拒绝,都在所有输入的 Promise 都已敲定时后返回所有结果。
具体使用哪里API根据实际业务需求决定。
面试官再问:
那这两个API能保证请求的先后顺序吗?
面试同学回答:
这两个api都是并发请求,它只是聚合了多个Promise的结果,但无法保证请求的先后顺序,如果请求有先后依赖的话,还是需要再Promise完成以后执行下一个请求。
以下是我实现一个allSettled
可以解决这个问题:
/**
* APromise: 请求Promise数组
* dependentRequestOrder: 是否有依赖的请求顺序
* return: Promise对象
* **/
function myAllSettled(APromise, dependentRequestOrder = false) {
return new Promise((resolve) => {
const results = [];
const len = APromise.length;
let index = 0;
let count = 0;
function _request() {
const i = index;
const currentPromise = APromise[i];
index++;
currentPromise.then((res) => {
results[i] = { status: 'fulfilled', value: res };
})
.catch(err => {
results[i] = { status: 'rejected', reason: err };
})
.finally(() => {
count++;
// 请求都完成结束返回
if (count === len) {
return resolve(results);
}
// 请求有依赖的情况,需要等待所有请求完成后再执行
if (dependentRequestOrder) {
_request();
}
})
}
// 请求依赖前后顺序
if (dependentRequestOrder) {
return _request();
}
// 并发请求,请求不依赖的前后顺序
for (let i = 0; i < len; i++) {
_request();
}
});
}
测试源码
下载地址: 前端DEMO/myAllSettled.html