aurora-article
aurora-article copied to clipboard
Promise 的一些简单处理
关于 Promise 的一些异步操作整理,包括 同时获取、顺序获取、获取最快的promise、超时处理等。
模拟请求数据
const getData = (message, time = 1000, type = "resolve") => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (type === "resolve") {
resolve({ statusCode: 200, message });
} else {
reject({ statusCode: 400, message });
}
}, time);
});
};
获取非异步值的promise
const resolveFunc = async () => {
const promise = Promise.resolve(123);
const res = await promise;
};
resolveFunc();
同时获取
const AllGet = async () => {
//Promise.allSettled同时获取,返回的Promise都将被兑现,而Promise.all中存在拒绝的promise则会报错,catch会捕获第一个拒绝的promise的值
const results = await Promise.allSettled(
Array.from({ length: 6 }).map((value, index) => {
if (index === 2 || index === 5) {
return getData(index, 1000, "reject");
} else {
return getData(index);
}
})
);
};
AllGet();
顺序获取
//需要将promise写成函数返回的格式,不写成函数reduce中是不会进行等待的
//顺序获取往往是下一个promise需要上一个的结果作为参数,写成函数用以传递参数
const SequenceGet = async () => {
Array.from({ length: 6 }).reduce(async (promiseChain) => {
const res = await promiseChain;
return getData(res.message + 10);
}, getData(1));
};
SequenceGet();
如果使用reduce方式难以理解,也可以使用for循环的方式,但是不要用数组的forEach函数,forEach函数是不会等待异步的。
const arr = Array.from({ length: 6 }, (_, index) => (prevData) => {
return getData(prevData === null ? index + 1 : index + 1 + prevData);
});
let prevData = null;
for (let promise of arr) {
let nowData = await promise(prevData);
prevData = nowData;
console.log(nowData);
}
从promise数组中获取一个最快的promise
使用 Promise.race
//从promise数组中获取一个最快的promise
const receFunc = async () => {
//常用做请求超时重试请求或报错
const res = await Promise.race([
getData(1, 1000),
getData(3, 500, "reject"),
getData(2, 2000),
]).catch((err) => console.log(err));
};
receFunc();
使用 Promise.any,比较新的方法,相较于 Promise.race 更符合日常使用场景。
const anyFunc = async () => {
//和race的区别是获取到的promise必须是成功的
const res = await Promise.any([
getData(1, 1000),
getData(2, 2000),
getData(3, 500, "reject"),
]);
};
anyFunc();
重复请求,三次都失败才放弃,且每次请求时间不能超过2s
function retryGet() {
let retryNumber = 0;
return function _retry() {
//只重试三次
retryNumber++;
//模拟数据,第三次为成功,前两次都是失败
let promises = [];
if (retryNumber === 3) {
promises = [getData(1, 1000), getData(0, 2000, "reject")];
} else if (retryNumber < 3) {
promises = [getData(0, 1000, "reject"), getData(0, 2000, "reject")];
} else if (retryNumber > 3) {
retryNumber = 0;
return Promise.resolve({ statusCode: 400, message: 0 });
}
return new Promise((resolve, reject) => {
Promise.race(promises)
.then((res) => {
retryNumber = 0;
resolve(res);
})
.catch((err) => reject(err));
}).catch((err) => {
return _retry();
});
};
}
async function test() {
const data = await retryGet()();
console.log(data);
}
test();