并发? 处理并发
因为js是单线程的,所以前端的并发指的是在极短时间内发送多个数据请求,比如说循环中发送 ajax , 轮询定时器中发送 ajax 请求. 然后还没有使用队列, 同时发送 的.
1. Promise.all
可以采用Promise.all
处理并发, 当所有promise
全部成功时, 会走.then
,并且可以拿到所有promise
中传进resolve
中的值
Promise.all([ WsApi.querySpyTaskSummary(), WsApi.querySpyTask(), ]).then((res) => { console.timeEnd(); });
2. async/await (个人喜欢用这个)
javascript
data() {
return {
timer: null, // 定时器名称 队列
timerRefresh: null, // 定时器 2小时刷新页面
}
},
mounted() {
this.startTimer() // 定时发送请求获取数据并更新对象 3s
this.startTimerRefresh() // 定时刷新页面 2h
// this.startDayCap()// 日产能 3s
// this.startMonthCap() // 月产能 5s
// this.startOnlineTime()// 在线时长(小时) 10s
},
beforeDestroy() {
// console.log('关闭定时器')
if (this.timer) {
clearInterval(this.timer)
clearInterval(this.timerRefresh)
// clearInterval(this.timerDayCap)
// clearInterval(this.timerMonthCap)
// clearInterval(this.timerOnlineTime)
}
},
methods: {
// #####################################################################
// 定时器 队列
startTimer() {
this.fetchAll() // 开始请求一次
if (this.timer) clearInterval(this.timer) // 清空上一个定时器
// 开启定时器
this.timer = setInterval(() => {
this.fetchAll() // 机器人状态汇总
// 优化释放异步资源方案未使用
// setTimeout(() => {
// this.fetchAll() // 机器人状态汇总
// }, 0)
}, 3000)
},
//定时刷新页面
startTimerRefresh() {
if (this.timerRefresh) clearInterval(this.timerRefresh)
this.timerRefresh = setInterval(() => {
window.location.reload(true)
// 刷新
console.log("刷新");
}, 2 * 60 * 60 * 1000) // 2 h
},
//
//
//
async fetchAll() {
// 日产能定时器
await WeldHomeGetGroupDayCap().then(res => {
// console.log(res, '日--------------');
if (res.code === 200) {
//
// this.props_productComponent_day = {}
//
this.props_productComponent_day = {
dataName: res.data.map(item => item.robotName),
dataNum: res.data.map(item => item.realCap.toFixed(2) * 1)
}
// console.log(this.props_productComponent_day);
} else {
// this.msgError('err')
}
}).catch(err => {
})
// 月产能
await WeldHomeGetGroupMonthCap().then(res => {
// console.log(res, '月产能--------------');
if (res.code === 200) {
//
// this.props_productComponent_month = {}
//
// const seriesData = day_xAxis_series_Data.map((item, index) => {
// return item.map(item => {
// return Number(item.rate)
// })
// })
this.props_productComponent_month = {
robotNameList: res.data.map(item => item.robotName), // x轴
seriesData: res.data.map(item => item.realCap.toFixed(2) * 1) // y轴
}
} else {
// this.msgError('err')
}
}).catch(err => {
})
// 放 try catch也可以的,因为有的会结合使用
try {
// let 变量1
// let 变量2
// await 1
// await 2
} catch (error) {
// console.log(111);
}
}
每隔几秒请求一次接口(轮询)页面过段时间会卡死?
如果要求不高的话,最简单的就是 定时刷新, 如上边的2小时刷新方案.
当然,首先我们要排查是哪方面的错误, 后端接口的问题,还是前端代码执行顺序的问题,并发是否串行了. 等等......
eg: 某个页面放置一段时间(几分钟,几小时,几天),点不了,刷新页面也要很长时间才能响应或者不响应. 卡顿问题,只有关闭页面,重新打开才正常 ===>>> 浏览器内存堆满问题, 比较明显的,谷歌快照能看到 (performance快照、memory快照)
单纯使用setInterval会使页面卡死,setTimeout自带清除缓存,组合使用实现轮询可解决浏览器崩溃
javascript
window.setInterval(() => {
setTimeout(fun, 0)
}, 30000
javascript
<script>
export default {
data() {
return {
num: 0,
timer: null,
};
},
destroyed() {
//离开页面是销毁
clearInterval(this.timer);
this.timer = null;
},
created() {
// 实现轮询
this.timer = window.setInterval(() => {
setTimeout(this.getProjectList(), 0); // 发送请求
}, 3000);
},
methods: {
stop() {
clearInterval(this.timer);
this.timer = null;
},
// 请求是否有新消息
getProjectList() {
console.log("请求" + this.num++ + "次");
if(this.num==8){
this.stop()
}
}
}
};
</script>