方案1: 请求队列
export default class RequestQueue {constructor(maxConcurrent) {this.maxConcurrent = maxConcurrent; this.currentConcurrent = 0; this.queue = []; this.requestId = 0; }add(request, meta = {}) {return new Promise((resolve, reject) => {const id = ++this.requestId;this.queue.push({id,request: () => request().then(res => ({id,res})), 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';
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;});
};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.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赋值即可