关于js,promise并发问题
async function test1 (data, index, limit) { let len = data.length let result = [] while (index < len) { let res = await fnFunction() result = result.concat(res) index += limit } return result }
await等待太久,页面卡顿,浏览器卡死
async function asyncPool (poolLimit, array, iteratorFn) { const ret = [] // 用于存放所有的promise实例 const executing = [] // 用于存放目前正在执行的promise for (const item of array) { const p = Promise.resolve(iteratorFn(item)) // 防止回调函数返回的不是promise,使用Promise.resolve进行包裹 ret.push(p) if (poolLimit <= array.length) { // then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除 const e = p.then(() => executing.splice(executing.indexOf(e), 1)) executing.push(e) if (executing.length >= poolLimit) { // 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更, // 状态变更后,就会执行上面then的回调,将该promise从executing中删除, // 然后再进入到下一次for循环,生成新的promise进行补充 await Promise.race(executing) } } } return Promise.all(ret) }
Promise.all太多会卡死
/** * arrs 请求数据源数组 * limit 是每次并行发起多少个请求 * handleFn 就是异步处理函数 */ async function limitQueueFn (arrs, limit, handleFn) { // 完成任务数 let runningIndex = 0 // 这是正在执行的下标 let finishedIndex = 0 // 这是已经执行完的下表 let result = new Array(arrs.length).fill(0) // 建立一个空数组, 存储结果 return new Promise((resolveFn, rejectFn) => { // 第一次的时候 一次性执行 limit 个任务 for (let i = 0; i < limit; i++) { run() } // 执行一个任务 function run () { // 构造待执行任务 当该任务完成后 如果还有待完成的任务 继续执行任务 new Promise((resolve, reject) => { const value = arrs[runningIndex] runningIndex++ // 这个是同步操作 resolve(handleFn(value)) }).then((res) => { result[finishedIndex] = res finishedIndex++ if (runningIndex < arrs.length) { run() } else { // 全部执行完毕 resolveFn(result) } }) } }) };
栈太深,卡死
async function finallyFn (data, max) { let pool = [] for (let i = 0; i < queueList.length; i++) { let promise = Fn() promise.then((res) => { console.log(`id${res}的请求已经处理完毕,当前并发为${pool.length}`) pool.splice(pool.indexOf(promise), 1) }) pool.push(promise) //这里是重点,当满了就阻塞 if (pool.length == max) { await Promise.race(pool) } } return data.length }
防止promise.all过多卡死,去除promise.all,采用setinterval等待结果,结束进程,对于项目可用