前端如何控制并发请求举例详解 |
前言什么情况需要前端控制并发请求,在需要多次才能请求完所需数据的时候 。比如接口一次返回,数据很多,让浏览器渲染卡顿甚至崩溃,这时候我们可以分批同时发出6个请求,这样就可以避免卡顿或者崩溃 。 那么前端如何控制并发请求呢? 前端控制并发请求的关键思路比如有 20 个请求,需要按照 关键思路,把请求方法和请求参数使用一个数组存起来,然后每次请求3个,请求完毕后再请求下一个3个 。每组请求返回后,把结果保存起来,等所有请求都返回后,再把所有结果返回 。 api 设计
代码实现function pControl(limit) { const taskQueue = [] // {task: Function, params: any[]}[] return { add, start } function add(task, params) { taskQueue.push({ task, params }) } function start() { return runAllTasks() } function runAllTasks() { const allResults = [] return new Promise((resolve) => { runTask() function runTask() { if (taskQueue.length === 0) { // 递归结束 return resolve(allResults) } const needRunSize = Math.min(taskQueue.length, limit) const tasks = taskQueue.splice(0, needRunSize) const promises = tasks.map(({ task, params }) => task(params)) Promise.all(promises).then((resList) => { allResults.push(...resList) // NOTE 递归调用的位置很关键 runTask() }) } }) } } 关键代码解读
能,需要使用 async function runAllTasks2() { const allResults = [] const groupArr = [] let startIndex = 0 // 划分分组 while (startIndex < taskQueue.length) { const arr = taskQueue.slice(startIndex, startIndex + limit) groupArr.push(arr) startIndex += limit } for (let index = 0; index < groupArr.length; index++) { const pList = groupArr[index].map(({ task, params }) => task(params)) const res = await Promise.all(pList) allResults.push(...res) } return allResults }
使用 async function runAllTasks2() { const allResults = [] const groupArr = [] let startIndex = 0 // 划分分组 while (startIndex < taskQueue.length) { const arr = taskQueue.slice(startIndex, startIndex + limit) groupArr.push(arr) startIndex += limit } // 迭代分组 const it = groupArr.entries() for (const [key, value] of it) { const pList = value.map(({ task, params }) => task(params)) const res = await Promise.all(pList) allResults.push(...res) } return allResults } 循环和 Promise 结合是怎样使用的呢?
完善 api,让其更加易用
这两个改进很简单 。先看用法: const asyncTaskControl = pControl() // 默认 6 asyncTaskControl.add(task, params1) asyncTaskControl.add(task, params2) // ... asyncTaskControl.add(task, params10) asyncTaskControl.start((res, doneSize) => { // 获取每组请求的结果 和当前完成了多少请求 console.log(res) // [{index:number,result:data}] console.log(doneSize) }).then(allResults => { // 所有请求结果 console.log(allResults) })
方便使用者拿当前并发请求的结果,方便计算完成进度 。 把上述功能封装成 p-control npm 包发布npm: p-control 可通过 小结
到此这篇关于前端如何控制并发请求的文章就介绍到这了,更多相关前端控制并发请求内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持! |