最近在项目中遇到一个bug,在订单支付逻辑处,总是会重复提交订单数据,经过两天排查终于找到了问题原因,这次错误不是逻辑问题而是
console.log断点打印造成的bug,具体代码如下
/**
* 事件回调
* 接收 payment 组件 gopay()回调
*/
onChangeFun: function(e) {
let opt = e;
let action = opt.action || null;
let value = opt.value != undefined ? opt.value : null;
console.log('action=== ',action)
console.log('this[action]=== ',this[action])
// console.log(' this[action](value)=== ', this[action](value))
// 这行打印会导致后续调用事件重复执行? 是什么原因?
action && this[action] && this[action](value);
},
让AI解释了下,答案如下
console.log(' this[action](value)=== ', this[action](value)) 这一行调用了 this[action](value),并将结果打印出来。如果 this[action] 是一个会触发 onChangeFun 函数的事件处理函数,那么这就会导致该事件的重复执行。
原因分析
- 事件回调的直接调用:
如果this[action]是一个事件处理函数,那么在你调用this[action](value)时,它实际是直接执行那个函数。如果这个函数内部有逻辑来触发onChangeFun,比如通过某种事件触发机制(例如 DOM 事件),那就会导致onChangeFun被再次调用,从而形成递归。 - 事件的触发和冒泡:
在许多事件模型中,比如 DOM 事件,某些事件会被冒泡(即父级元素也会收到这个事件),导致父级的事件处理程序也会被触发。如果this[action]处理了事件并且这个事件又向上冒泡了,就会再次触发相同的事件处理程序。 - 状态变更引发的再渲染:
在一些框架(如 React、Vue等)中,组件状态的变更可能会导致重渲染,从而触发相关的生命周期函数或事件回调。如果this[action]导致了状态/属性的更改,会在下一个渲染周期中再次调用onChangeFun。
解决方案
- 避免直接调用:
如果需要在控制台中打印函数的返回值而不希望它执行,可以考虑使用其他方法来打印,例如使用一个包装函数或将其结果存储在变量中。 - 使用状态检查:
在事件处理函数的开头增加一个状态标识,比如isProcessing,来阻止同一事件在处理完成之前再次执行。javascript - 调试:
仔细查看被调用的this[action]函数的具体实现,确保没有意外的逻辑或API调用会触发onChangeFun的再执行。
在此记录下,以后在遇到了好知道怎么解决
