最近在项目中遇到一个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
的再执行。
在此记录下,以后在遇到了好知道怎么解决