VUE解决页面请求接口大规模并发的问题(请求队列) - 实践

方案1: 请求队列

// RequestQueue.js 
export
default
class RequestQueue {
constructor(maxConcurrent
) {
this.maxConcurrent = maxConcurrent;
// 最大并发请求数
this.currentConcurrent = 0
;
// 当前并发请求数
this.queue = []
;
// 请求队列
this.requestId = 0
;
// 请求ID计数器
}
add(request, meta = {
}
) {
return
new Promise((resolve, reject
) =>
{
const id = ++
this.requestId;
this.queue.push({
id,
request: (
) =>
request(
).then(res =>
({
id,
res
}
)
)
, // 响应携带ID
resolve,
reject,
meta, // 可携带业务标识
}
)
;
this.processQueue(
)
;
}
)
}
processQueue(
) {
while (
this.queue.length >
0 &&
this.currentConcurrent <
this.maxConcurrent) {
const task =
this.queue.shift(
)
;
this.currentConcurrent++
;
task.request(
)
.then(({
id,
res
}
) =>
{
task.resolve({
id,
meta: task.meta,
data: res
}
)
;
// 返回完整响应
}
)
.catch(task.reject)
.finally((
) =>
{
this.currentConcurrent--
;
this.processQueue(
)
;
}
)
;
}
}
}

组件调用

import request from '@/utils/request.js'
;
/** axios的二次封装 */
import RequestQueue from '@/utils/RequestQueue.js'
;
// 使用请求队列
const requestQueue =
new RequestQueue(3
)
;
// 设定最大并发请求数
const urls = [
{
url: '/slider/getSliders'
,
method: ''
, // 请求方法
data: ''
, // 请求参数
id: 1
,
reqType: 'getSliders' // 请求唯一标识符
}
,
{
url: '/course/mostNew'
,
method: 'post'
,
data: newCoursePageInfo,
id: 2
,
reqType: 'mostNew'
}
,
{
url: '/course/search'
,
method: 'post'
,
data: interestCoursePageInfo,
id: 3
,
reqType: 'search'
}
]
;
// 请求函数:
const fetchData = ({
url, method, data
}
) =>
{
return request(url, data, method).then((res
) =>
{
return res;
// res.json(); // 如果是Fetch API必须要显式调用.json()方法解析响应体,注释上边用这个
}
)
;
}
;
const requests = urls.map((url
) =>
(
) =>
fetchData(url)
)
;
onLoad((
) =>
{
Promise.all(requests.map((req, idx
) => requestQueue.add(req, {
originalIndex: idx, reqType: urls[idx].reqType
}
)
)
).then((results
) =>
{
// results包含[{id, meta, data},...] data:响应回的数据
results.forEach(({
meta, data
}
) =>
{
switch (meta.reqType) {
case 'getSliders': // 请求唯一标识符
swiperList.value = data.list;
break
;
case 'mostNew':
interestCouseInfo.value.push(...data.pageInfo.list)
;
break
;
case 'search':
newCourseInfo.value = data.pageInfo.list.slice(3
, 9
)
;
break
;
}
console.log(`请求${meta.originalIndex
}(${meta.reqType
})结果:`
, data)
;
}
)
;
}
)
;
}
)
;

说明:

  • reqType: 请求唯一标识符,用于将并行发出的请求与响应回的数据对应上
  • request: 对axios做的二次封装,函数fetchData 发出的请求就好比在api文件中的请求函数在这里插入图片描述只需在 对象urls变动url(id可不需要,唯一标识符必须) 和在 results赋值即可
posted @ 2025-07-23 11:19  wzzkaifa  阅读(67)  评论(0)    收藏  举报