有这样一个问题,在发送一个大文件时会用到分片处理,或者其他批量认证用户的时候,如果一个地址一个地址发送用户体验会特别差,或者有个文件特别大,请求等待时间长,这个情况体验会非常不好,我查阅了一些资料和视频做了下面的并发请求
/**
* 并发请求 用于大文件分片
* @param { string[] } urls 待请求的 url 数据
* @param { number } maxNum 最大并发数据
*/
// 功能: concurrently 请求多个 url,并返回请求结果
// 参数:urls:url数组;maxNum:最大并发请求数
function concurRequest(urls, maxNum) {
if (!urls || !urls.length) {
// 如果urls为空,则返回空数组
return new Promise((resolve, reject) => {
resolve([]);
})
}
// 使用 Promise 实例化一个异步操作,用于处理并发请求
return new Promise((resolve, reject) => {
let index = 0; // 指向下一次请求坐标
let results = []; // 存储请求结果
async function _request() {
const i = index;
const url = urls[i];
index += 1;
try {
// 使用 fetch 函数发起请求
const resp = await fetch(url);
// 将请求结果存储在 results 数组中
results[i] = resp;
} catch (error) {
// 如果请求失败,将错误存储在 results 数组中
results[i] = error;
}
}
_request()
_request()
_request()
})
}
目前看着请求数据是没有问题,目前只是做了三次请求,但是还有一个最大的问题就是怎么去做最大请求数,还需要考虑的一个问题就是什么时候请求下一个, 我们可以这样认为当前有一个请求完了,就请求下一项
function concurRequest(urls, maxNum) {
if (!urls || !urls.length) {
// 如果urls为空,则返回空数组
return new Promise((resolve, reject) => {
resolve([]);
})
}
// 使用 Promise 实例化一个异步操作,用于处理并发请求
return new Promise((resolve, reject) => {
let index = 0; // 指向下一次请求坐标
let results = []; // 存储请求结果
async function _request() {
const i = index;
const url = urls[i];
index += 1;
try {
// 使用 fetch 函数发起请求
const resp = await fetch(url);
// 将请求结果存储在 results 数组中
results[i] = resp;
} catch (error) {
// 如果请求失败,将错误存储在 results 数组中
results[i] = error;
}
finally {
if (index < urls.length) {
_request()
}
}
}
_request()
_request()
_request()
})
}
最终还要考虑一个问题就是正 promise 什么时候完,也就是说当某一个请求完成,要返回所有的数据
function concurRequest(urls, maxNum) {
if (!urls || !urls.length) {
// 如果urls为空,则返回空数组
return new Promise((resolve, reject) => {
resolve([]);
})
}
return new Promise((resolve, reject) => {
let index = 0; // 指向下一次请求坐标
let results = []; // 存储请求结果
let count = 0; // 当前正在进行的请求数
async function _request() {
const i = index;
const url = urls[i];
index ++;
try {
const resp = await fetch(url);
results[i] = resp;
} catch (error) {
results[i] = error;
} finally {
count++;
if( count == urls.length){
// 当所有请求都完成时,将结果 resolve 出去
resolve(results);
}
if (index < urls.length) {
_request()
}
}
}
for (let i = 0; i < maxNum && i < urls.length; i++) {
_request();
}
})
}
还请各位大佬进行评论,感谢!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。