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

如何用Google Apps Script在侧边栏实时更新运行状态消息?

解决Google Apps Script实时显示运行进度的问题

核心问题原因

google.script.run采用单次请求-响应机制,服务器端函数只有执行完毕后才会将返回值传递给withSuccessHandler,无法在函数运行过程中主动向客户端推送中间状态。要实现实时进度展示,需采用客户端定时查询服务器端存储进度的方案。

可行实现方案

1. 服务器端:用PropertiesService存储进度,优化计算逻辑

通过PropertiesService存储当前进度与任务状态,拆分长任务为可追踪的结构,同时提供进度查询接口:

function computePO() {
  // 初始化进度与状态
  const userProps = PropertiesService.getUserProperties();
  userProps.setProperty('progress', '0');
  userProps.setProperty('status', 'running');
  
  const total = 10000;
  for (let i = 1; i <= total; i++) {
    // 替换为你的实际耗时业务逻辑
    Utilities.sleep(1);
    
    // 每100次循环更新一次进度(减少存储操作频率,提升性能)
    if (i % 100 === 0) {
      const progressPercent = Math.round((i / total) * 100);
      userProps.setProperty('progress', `${progressPercent}%`);
    }
  }
  
  // 任务完成后更新状态
  userProps.setProperty('progress', '100%');
  userProps.setProperty('status', 'done');
  return 'done';
}

// 供客户端查询进度的接口函数
function getProgress() {
  const userProps = PropertiesService.getUserProperties();
  return {
    progress: userProps.getProperty('progress') || '0',
    status: userProps.getProperty('status') || 'idle'
  };
}

2. 客户端:定时轮询进度,更新UI

在HTML侧边栏中,启动计算任务后通过setInterval定时查询进度,直到任务完成后停止轮询:

<!DOCTYPE html>
<html>
  <body>
    <div id="msg">等待任务开始...</div>
    <button onclick="startCompute()">开始计算</button>
    
    <script>
      let pollInterval;
      
      function startCompute() {
        document.getElementById('msg').innerHTML = '任务启动中...';
        // 启动服务器端计算任务
        google.script.run
          .withSuccessHandler(() => {
            // 任务完成后清除轮询并更新提示
            clearInterval(pollInterval);
            document.getElementById('msg').innerHTML = '任务完成!';
          })
          .withFailureHandler((err) => {
            // 出错时终止轮询并提示错误
            clearInterval(pollInterval);
            document.getElementById('msg').innerHTML = `出错:${err.message}`;
          })
          .computePO();
        
        // 每500ms查询一次进度
        pollInterval = setInterval(() => {
          google.script.run
            .withSuccessHandler(updateProgress)
            .getProgress();
        }, 500);
      }
      
      function updateProgress(data) {
        if (data.status === 'running') {
          document.getElementById('msg').innerHTML = `当前进度:${data.progress}`;
        }
      }
    </script>
  </body>
</html>

注意事项

  • 轮询间隔不要小于300ms,避免触发GAS的调用频率限制
  • 任务完成或出错后必须清除setInterval,防止无效请求
  • 多用户场景下必须使用PropertiesService.getUserProperties()(每个用户独立存储进度),避免进度串号
  • 可根据任务实际耗时调整进度更新的频率(示例中每100次循环更新一次,减少存储操作次数)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:52:46