项目背景
购物车修改商品数量
代码
async skuNumChange(num, index) {
//规定修改后的值必须为整数且大于0,同时非数字无法通过
if (this.cartInfoList[index].skuNum + num > 0 && num % 1 === 0) {
const { code } = await reqAddOrUpdateShopCart( //发起请求修改数量
this.cartInfoList[index].skuId,
num //增加或减少多少商品,正数为加,负数为减
);
if (code != 200) {
alert("修改失败");
}
} else {
alert("输入有误,请重新输入");
}
this.getDate(); //发起请求返回购物车数据
},
当快速点击“-”号时,数量会小于1,原因是没有进行节流处理,当快速点击时,异步请求没来得及返回服务器的最新数据,所以此时浏览器商品数量还没有发生改变,跳过了判断条件
(比如现在数量为2,快速点击,第一次点击修改后的数据为1,发起请求修改商品数量,第二次点击,此时浏览器端 cartInfoList 中的商品数量仍为2,所以通过判断条件,再次发起请求修改商品数量,最终商品数量为2-1-1=0,出现bug)
解决
一般方法是用节流,在这里用lock锁实现
data() {
return {
lock: true, //加上锁防止点击过快
};
},
async skuNumChange(num, index) {
if (this.lock){
this.lock = false;
//规定修改后的值必须为整数且大于0,同时非数字无法通过
if (this.cartInfoList[index].skuNum + num > 0 && num % 1 === 0) {
const { code } = await reqAddOrUpdateShopCart( //发起请求修改数量
this.cartInfoList[index].skuId,
num //增加或减少多少商品,正数为加,负数为减
);
if (code != 200) {
alert("修改失败");
}
} else {
alert("输入有误,请重新输入");
}
this.getDate(); //发起请求返回购物车数据
}
},
锁的原理是定义一个变量,初始值为true,在进入只能同步修改数据的代码段(临界区)时上锁(变量=false),在离开时解锁(变量=true),在这里在data中创建一个变量lock作为锁,在进入回调函数skuNumChange时进行判断,因为lock初始值为true,所以第一次必定进入,上锁,此时如果快速点击,因为lock为false,无法进入代码段,上锁成功。
需要注意的是,不能在回调函数skuNumChange中解锁,因为只有getDate发送请求,改变了浏览器端的数据之后才能解锁,否则问题的根本没有解决,跟上面一样
watch: {
cartInfoList(newVal, oldVal) {
this.lock = true;
},
},
在这里通过watch监听cartInfoList数据,当数据改变时解锁