如何在Google Apps Script脚本运行过程中实时更新Web App前端界面
Google Web App 后端脚本执行实时进度同步方案
实现原理
Google Apps Script的google.script.run是单次HTTP请求模型,只有服务端函数执行完成/报错才会返回结果,本身不支持服务端主动推送消息到前端。可以通过用户缓存存储进度+前端轮询拉取的方案实现实时更新:
- 服务端执行
doStuff的每个阶段,把当前进度写入当前用户的私有缓存 - 前端触发
doStuff的同时开启定时轮询,定期调用专用接口拉取最新进度,更新到页面对应位置 - 任务执行完成/报错后停止轮询,清理缓存
修改后的服务端代码(code.gs)
// 引入用户私有缓存,每个用户的进度独立不冲突 const userCache = CacheService.getUserCache() function doStuff() { // 初始化进度,缓存有效期设为10分钟,覆盖任务最长运行时间即可 userCache.put('task_progress', '开始执行第一步...', 600) // 执行第一步逻辑(替换为实际业务代码) Utilities.sleep(2000) userCache.put('task_progress', '第一步完成,开始执行第二步...', 600) // 执行第二步逻辑(替换为实际业务代码) Utilities.sleep(2000) userCache.put('task_progress', '第二步完成,开始执行第三步...', 600) // 执行第三步逻辑(替换为实际业务代码) Utilities.sleep(2000) const finalResult = '所有任务执行完成' // 任务结束清理缓存 userCache.remove('task_progress') return finalResult } // 专供前端拉取进度的接口 function getProgress() { return userCache.get('task_progress') || '' }
修改后的前端代码(page.html)
<button id="btn">Run function</button> <!-- 进度展示容器 --> <span id="updates" style="color: #666; display: block; margin: 8px 0;"></span> <!-- 最终结果容器 --> <span id="result_span"> <!--return value from doStuff goes here--> </span> <script> document.getElementById("btn").addEventListener("click",init_function); function init_function(){ console.log('init') const updateLocation = document.querySelector('#result_span') const progressLocation = document.querySelector('#updates') // 存储轮询定时器ID,后续用来停止轮询 let progressTimer = null // 开启进度轮询,每1.5秒拉一次进度 progressTimer = setInterval(() => { google.script.run .withSuccessHandler(progress => { if(progress) progressLocation.innerHTML = progress }) .getProgress() }, 1500) function onFailure(error){ // 报错先清除轮询 clearInterval(progressTimer) progressLocation.innerHTML = '' const warning = `<span style="color:red">${error}</span>`; updateLocation.innerHTML = warning; }; function onSuccess(result){ // 任务完成清除轮询 clearInterval(progressTimer) progressLocation.innerHTML = '' updateLocation.innerHTML = result; }; google.script.run.withFailureHandler(onFailure) .withSuccessHandler(onSuccess) .doStuff(); } </script>
注意事项
- 轮询间隔建议设置在1000ms以上,避免频繁请求触发Google Apps Script的调用频率限制
- 如果有多个并行任务的需求,可以给每个任务生成唯一ID,缓存的时候用ID作为key区分不同任务的进度
- 缓存有效期需要设置为大于你业务任务的最长执行时间,避免执行过程中缓存过期丢失进度
内容的提问来源于stack exchange,提问作者redditor
相关产品推荐
相关产品推荐

