我是如何控制1000|我是如何控制1000 个 Echarts 实例同时渲染 最大并发的
Demo 地址
先上 demo 地址
https://codepen.io/firstblood...
项目背景
随着 面向领导编程
越来越深入人心, 看板
项目想必是每个前端开发专家的必修之路
产品经理 张三
要求 前端开发专家 红盾
做一个由 1000个图表定时刷新
的公司最新的财务支出情况
红盾
在 chrome
上 一顿操作猛如虎,没两三天就把 项目搞定了 交付给产品经理 张三
.
无并发控制
让我们来看看 红盾
此时大致的代码情况
.chart {
float: left;
width: 360px;
height: 300px;
margin: 10px;
border: 2px solid #ff9900;
}
结果
张三
不按套路出牌, 在电视机上偷偷安了个 浏览器(性能极差),然后输入地址 xxx.com
(自行脑补)...直接把浏览器给淦奔溃了...没错,
红盾
此时的内心文章图片
这时候 他想起了 后端大佬
老黄
,老黄给了他一个思路 控制并发
实现控制并发 实现并发
- 首先我们来实现一个控制
并发函数
完整代码
查看/**
* @params {Number} poolLimit -最大并发限制数
* @params {Array} array -所有的并发请求|渲染数组
* @params {Function} iteratorFn -对应执行的并发函数(接受 array 的每一项值)
*/
async function asyncPool(poolLimit, array, iteratorFn) {
const ret = [] // 所有执行中的 promises
let executing = [] // 正在执行中的 promises
for (const item of array) {
//接受 iteratorFn 的返回值:Promise
const p = Promise.resolve().then(() => iteratorFn(item))
ret.push(p)
// 如果执行的数组 大于等于 最大并发限制 那么我们就要控制并发
if (array.length >= poolLimit) {
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
// p.then 返回的 一个Promise 我们把它放到正在执行数组中,一旦执行完 便剔除对应的值
executing.push(e)
//核心代码:正在执行的 promises 数组 大于等于 `最大并发限制` 用.race 方法释放一个执行最快的
if (executing.length >= poolLimit) await Promise.race(executing)
}
}
//返回一个 Promise.all
return Promise.all(ret)
}
- 改造
renderChartList
函数(核心
)
async renderChartList() { // 这里的 MAX_CURRENT 之后可以自定义一个数字 await asyncPool(MAX_CURRENT, this.domList, (dom) => { // 我们在这里必须返回一个 promise 对应为 `并发函数` 的 `p` 变量 return new Promise(async (resolve) => { const res = await this.initChart(dom); resolve(res); // 这一步之后, 对应执行 `并发函数` 的 p.then 剔除 }).then((data) => { console.log(data); return data; }); }); }
initChart
函数【我是如何控制1000|我是如何控制1000 个 Echarts 实例同时渲染 最大并发的】我们必须保证一个图表渲染完成,再执行下一个渲染,此时我们就需要监听
Echarts
的 finished
事件initChart(domId) {
// 我们 把它改造成一个 promise 函数
return new Promise((resolve) => {
...
// 核心代码 监听 echarts 的 finished
this.chartObjs[domId].on("finished", () => {
resolve(domId);
// 对应 上一步的 `const res = await this.initChart(dom);
`
});
});
}
4.改造
intervalChartData
函数我们必须保证并发执行完 所有的图表渲染,再进入下一个定时器逻辑
判断
executing
的长度即可(此时应该把 executing
独立为全局变量)intervalChartData(s) {
setInterval(() => {
if (executing.length > 0) return;
// 还有正在执行的渲染 不重复添加
this.renderChartList();
}, s);
}
完整代码 附上完整代码
.chart {
float: left;
width: 360px;
height: 300px;
margin: 10px;
border: 2px solid #ff9900;
}
小彩蛋 小彩蛋??,
红盾
说服张三
买了个高性能的电视机 完美解决...如有不对,欢迎指正 觉得有帮助,欢迎三连
推荐阅读
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 如何寻找情感问答App的分析切入点
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus使用queryWrapper如何实现复杂查询
- 如何在Mac中的文件选择框中打开系统隐藏文件夹
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- java中如何实现重建二叉树
- Linux下面如何查看tomcat已经使用多少线程
- thinkphp|thinkphp 3.2 如何调用第三方类库
- 2019女表什么牌子好(如何挑选女士手表?)