You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现SweetAlert取消按钮终止正在执行的脚本函数

实现原理

google.script.run发起的Google Apps Script服务端任务一旦启动,前端没有提供原生API可以直接强制中断运行中的进程,仅关闭SweetAlert弹窗只会销毁前端UI组件,完全不会影响后台已经在调度执行的脚本。要实现取消按钮终止后台执行的效果,需要采用协作式终止方案:前后端共享一个取消状态标记,后台脚本在执行过程中主动轮询检查标记状态,前端点击取消时更新标记值,后台检测到标记为取消时主动退出执行逻辑。

具体实现步骤
  • 第一步:在Apps Script服务端编写状态管理工具函数,用脚本属性存储取消标记,实现前后端状态共享
// 以下代码写在Apps Script后端代码文件中
// 重置取消标记(每次任务启动前、结束后调用)
function resetCancelFlag() {
  PropertiesService.getScriptProperties().setProperty('TASK_CANCELLED', 'false');
}

// 标记任务为取消状态(前端点取消时调用)
function markTaskCancelled() {
  PropertiesService.getScriptProperties().setProperty('TASK_CANCELLED', 'true');
}

// 检查当前任务是否已被取消(后台逻辑执行中轮询调用)
function isCancelled() {
  return PropertiesService.getScriptProperties().getProperty('TASK_CANCELLED') === 'true';
}
  • 第二步:改造原有的merge_Columns后台函数,在所有耗时节点插入取消检查,检测到取消信号时主动终止逻辑
// 改造后的列合并函数示例
function merge_Columns() {
  try {
    // 任务启动前先重置取消标记
    resetCancelFlag();
    const sheet = SpreadsheetApp.getActiveSheet();
    const totalColumns = sheet.getLastColumn();
    
    // 替换为你原有的列遍历/处理逻辑
    for (let col = 1; col <= totalColumns; col++) {
      // 每处理一列前检查一次取消状态
      if (isCancelled()) {
        return { code: -1, msg: '操作已被用户终止' };
      }
      // 此处写入你原有的同表头列合并逻辑
      // ...
    }
    return { code: 0, msg: '同表头列合并完成' };
  } catch (err) {
    return { code: 1, msg: `执行出错:${err.message}` };
  } finally {
    // 无论任务成功/失败/取消,结束后都重置标记,避免影响下次执行
    resetCancelFlag();
  }
}

注意:检查点的密度根据你的逻辑调整即可,一般每处理1列/每处理100行数据检查一次,密度过高会增加属性读写的性能开销,密度过低会导致取消操作响应延迟。

  • 第三步:改造前端代码,给SweetAlert的取消按钮绑定事件,点击取消时触发后端标记更新
<button class="button-68" role="button" onclick="morphf3994()">Unir columnas con el mismo encabezado</button>

<script>
function morphf3994() {
  showLoadingSwal();
  google.script.run
    .withSuccessHandler((res) => {
      Swal.close();
      if (res.code === -1) {
        Swal.fire('已终止', res.msg, 'info');
        return;
      }
      if (res.code === 1) {
        Swal.fire('执行失败', res.msg, 'error');
        return;
      }
      Swal.fire('执行成功', res.msg, 'success');
    })
    .withFailureHandler((err) => {
      Swal.close();
      Swal.fire('执行异常', err.message, 'error');
    })
    .merge_Columns();
}

function showLoadingSwal() {
  Swal.fire({
    titleText: "Ejecutando...",
    text: 'Por favor, no toques ni cierres el documento.',
    icon: 'warning',
    allowOutsideClick: false,
    showLoaderOnConfirm: true,
    showConfirmButton: false,
    showCancelButton: true,
    cancelButtonText: '终止执行',
    didOpen: () => {
      Swal.showLoading();
      // 绑定取消按钮点击事件
      const cancelBtn = Swal.getCancelButton();
      cancelBtn.onclick = () => {
        // 点击后先调用后端接口标记取消
        google.script.run.markTaskCancelled();
        // 禁用按钮避免重复点击
        cancelBtn.disabled = true;
        cancelBtn.innerText = '正在终止...';
      }
    }
  })
}
</script>
注意事项
  • 该方案为协作式终止,只有代码运行到你添加的isCancelled()检查点时才会退出,无法做到点击取消立刻强制杀死进程,这是Apps Script本身的平台限制,没有其他绕过方式。
  • 如果你的merge_Columns里存在无法拆分的长耗时单次操作(比如单次写入超大量数据、单次数十秒的接口请求),需要把长任务拆成多步小批量操作,才能插入检查点实现取消响应。
  • 如果是多用户同时使用的插件,建议给每次触发的任务生成唯一ID,将取消标记按任务ID存储在用户属性中,避免不同用户的操作互相干扰。

内容的提问来源于stack exchange,提问作者user19389364

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:09:33