最近在项目中遇到一个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 函数的事件处理函数,那么这就会导致该事件的重复执行。

原因分析

  1. 事件回调的直接调用
    如果 this[action] 是一个事件处理函数,那么在你调用 this[action](value) 时,它实际是直接执行那个函数。如果这个函数内部有逻辑来触发 onChangeFun,比如通过某种事件触发机制(例如 DOM 事件),那就会导致 onChangeFun 被再次调用,从而形成递归。
  2. 事件的触发和冒泡
    在许多事件模型中,比如 DOM 事件,某些事件会被冒泡(即父级元素也会收到这个事件),导致父级的事件处理程序也会被触发。如果 this[action] 处理了事件并且这个事件又向上冒泡了,就会再次触发相同的事件处理程序。
  3. 状态变更引发的再渲染
    在一些框架(如 React、Vue等)中,组件状态的变更可能会导致重渲染,从而触发相关的生命周期函数或事件回调。如果 this[action] 导致了状态/属性的更改,会在下一个渲染周期中再次调用 onChangeFun

解决方案

  1. 避免直接调用
    如果需要在控制台中打印函数的返回值而不希望它执行,可以考虑使用其他方法来打印,例如使用一个包装函数或将其结果存储在变量中。
  2. 使用状态检查
    在事件处理函数的开头增加一个状态标识,比如 isProcessing,来阻止同一事件在处理完成之前再次执行。

    javascript

    onChangeFun: function(e) {
    if (this.isProcessing) {
    return;
    }
    this.isProcessing = true;
    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)=== ', action && this[action] ? this[action](value) : null);

    action && this[action] && this[action](value);
    this.isProcessing = false;
    },

  3. 调试
    仔细查看被调用的 this[action] 函数的具体实现,确保没有意外的逻辑或API调用会触发 onChangeFun 的再执行。

在此记录下,以后在遇到了好知道怎么解决