js实现并发控制
一、使用promise实现并发控制
在前端优化性能的时候, 我们可以考虑使用并发控制
比如首页有10个并发请求, 先发送3个, 3个中哪一个响应了, 立即发送第4个, 直到第10个发送完成
function limitLoad(urls, handler, limit) { const sequence = [].concat(urls) let promise = [] promise = sequence.splice(0, limit).map((url, index) => { return handler(url).then(()=>{ return index }) }) let p = Promise.race(promise) // for循环给p赋值相当于.then().then()链式调用 for (let i= 0; i< sequence.length; i++) { p = p.then(res => { promise[res] = handler(sequence[i]).then(()=>{ return res }) return Promise.race(promise) }) } } const urls =[ {info:'1', time:2000}, {info:'2', time:1000}, {info:'3', time:2000}, {info:'4', time:2000}, {info:'5', time:3000}, {info:'6', time:1000}, {info:'7', time:2000}, {info:'8', time:2000}, {info:'9', time:3000}, {info:'10', time:1000} ] function loadImg(url){ return new Promise((reslove, reject)=>{ console.log(url.info + '---start') setTimeout(()=>{ console.log(url.info, 'ok!!!') reslove() }, url.time) }) } limitLoad(urls, loadImg, 3)
function asyncPool(poolLimit, array, iteratorFn) { let i = 0; const ret = []; // 存储所有的异步任务 const executing = []; // 存储正在执行的异步任务 const enqueue = function () { if (i === array.length) { return Promise.resolve(); } const item = array[i++]; // 获取新的任务项 const p = Promise.resolve().then(() => iteratorFn(item, array)); ret.push(p); let r = Promise.resolve(); // 当poolLimit值小于或等于总任务个数时,进行并发控制 if (poolLimit <= array.length) { // 当任务完成后,从正在执行的任务数组中移除已完成的任务 const e = p.then(() => executing.splice(executing.indexOf(e), 1)); executing.push(e); if (executing.length >= poolLimit) { r = Promise.race(executing); } } // 正在执行任务列表 中较快的任务执行完成之后,才会从array数组中获取新的待办任务 return r.then(() => enqueue()); }; return enqueue().then(() => Promise.all(ret)); }
Talk is cheap,show me the code