前端的并发请求通常指在同一时间点内,浏览器向服务器发送多个请求,并且这些请求可以同时处理而不阻塞彼此。这可以通过使用异步请求(如AJAX)或者Web Workers等来实现。通过并发请求,可以提高网页的加载速度和用户体验。
1.利用fetch
API和Promise.all
实现并发请求。
// 创建多个请求的URL数组
const urls = ['url1', 'url2', 'url3'];
// 发起并发请求的函数
async function fetchAllUrls(urls) {
// 将URL数组中的每个URL都通过fetch方法进行请求,
// 返回的是一个包含多个Promise对象的数组requests。
const requests = urls.map(url => fetch(url));
// 使用Promise.all方法等待所有请求完成,并将所有请求的结果
// 存储在responses中,返回的是一个包含多个Response对象的数组。
const responses = await Promise.all(requests);
// 将每个Response对象通过调用.json()方法转换为JSON格式,然后使用Promise.all
// 等待所有转换操作完成,返回的是一个包含多个JSON数据的数组data。
const data = await Promise.all(responses.map(response => response.json()));
return data; // 最后将处理完成的JSON数据数组作为结果返回。
}
// 调用并发请求函数并处理结果
fetchAllUrls(urls)
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error fetching data:', error);
});
2.原生JavaScript实现并发请求
index.js
function concurRequest(urls, maxNum) {
return new Promise((resolve) => {
if (urls.length === 0) {
resolve([])
return
}
const results = []
let index = 0 // 下一个请求的下标
let count = 0 // 当前请求完成的数量
// 发送请求
async function request() {
if (index === urls.length) {
return
}
const i = index
const url = urls[index]
index++
// console.log('index的值', index);
try {
const resp = await fetch(url) // 不确定三个并发的异步请求谁更快
// resp加入到results
results[i] = resp // 所以这里不用push
} catch (err) {
// 把err加入到results中
results[i] = err
} finally {
count++
if (count > urls.length) {
// console.log(over);
return resolve(results)
}
// 首次并发有三个请求,几乎同时发送,速度太快,index的值像直接跳到了3
// console.log('首次并发到这里后index的值', index);
request() // 也就是说这里以非常快的速度又同时请求了三次,造成了并发请求
}
}
const times = Math.min(maxNum, urls.length)
for (let i = 0; i < times; i++) {
// 三个请求在这里并发
request()
}
})
}
把 index.js 引入 ConcurrentRequests.html 中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./index.js"></script>
<script>
const urls = []
for (let i = 1; i <= 10; i++) {
urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`)
}
concurRequest(urls, 3).then((resps) => {
console.log(resps);
})
</script>
</body>
</html>