Vue.js框架:为避免短时间内以及调取接口后未返回数据期间进行重复操作的加锁问题(数据-时间联动双重锁)
一、问题描述
在页面中执行操作时,往往会遇到短时间内重复点击造成的多次触发问题,频繁调取接口。或者由于数据量较大,查询时间比较长,结果还没返回的时候,用户不耐烦了进行重复点击,同样会造成多次触发问题。
在遇到这类问题时,当然后台接口可以进行加锁,来避免接口重复调用。不过近期在做前端,因此尝试从前端进行限制。
遇到此类问题,基本就是设定一个属性,开始调取接口时调整属性的值,模拟加锁效果。在接口延时返回结果后,再调回该属性值,达到解锁效果。不过最近需要的效果则是设定一个最小时限,即如果数据返回的时间超过了这个最小时限的话,就在数据返回结果后解锁,可以继续进行操作;如果数据量较小,返回比较快,没有达到最小时限时,就暂时不解锁,等时限到了之后才允许继续操作。
这里就根据时间和数据设定了一个双重锁,根据vue里的监听来联动判断,对总锁结果进行调整。
二、代码如下
<template> <div id="app"> <button @click="clickEvent"></button> </div> </template> <script> export default { name: "test", data(){ return { //总锁,避免短时间内重复触发操作(操作时加锁,数据锁和时间锁都处于解锁的状态时解锁) finallyLock:false, //双重锁-数据锁(操作中调取接口前进行加锁,数据返回后解锁) dataLock:false, //双重锁-时间锁(操作中调取接口前进行加锁,定时时间到达后进行解锁) timeLock:false, //双重锁最小时限 minTime:3000, } }, watch:{ //监听数据锁 dataLock: function (val) { //数据锁调整到解锁状态时,即接口返回数据时 if(!val){ //联动时间锁进行判断 if(!this.timeLock){ //当数据锁解锁时,如果时间锁已解锁,双重锁解开,直接开锁 this.finallyLock = false; }else{ //当数据锁解锁时,时间锁还未解,则不进行操作,保证双重锁短时间内无法重复操作的最小时限 } } }, //监听时间锁 timeLock: function (val) { //时间锁加锁时,即开始执行操作时 if(val){ //变量代理 let that = this; //通过定时任务,在设定的最小时限后进行判断 setTimeout(function () { //联动数据锁进行判断 if(!that.dataLock){ //到时间时,如果数据锁已解锁,则双重锁解开,直接开锁 that.finallyLock = false; }else{ //到时间时,如果数据锁还未解锁,说明数据还未返回成功,数据返回时间超过设定的最小时限,总锁在数据锁解锁时同步解锁即可 } //定时结束后,不管逻辑结果如何,都结束时间锁 that.timeLock = false; },that.minTime); } } }, methods:{ //执行操作 clickEvent(){ //如果未加锁,可进行操作 if(!this.finallyLock){ //操作开始,总锁加锁 this.finallyLock = true; //调取接口前,开启数据锁和时间锁 this.dataLock = true; this.timeLock = true; //调取接口(伪代码) api().then(response=>{ //接口延时返回结果后,解锁数据锁 this.dataLock = false; }); } } } } </script> <style scoped> </style>
实际上就是两个锁并行,时间锁走定时任务,数据锁走接口,一个锁完成后在监听里判断另一个锁的状态,来进行后续的操作。