DOMContentLoaded触发时调用Google Apps Script取表格数组无返回值如何解决
问题原因
google.script.run是异步调用方法,触发后不会阻塞后续代码执行,你在调用sendData()后立刻尝试读取返回值,此时服务端还没有返回结果,同时你使用的变量e在DOMContentLoaded回调的当前作用域内未定义,自然拿不到任何值。- 你在
callBack回调函数内声明的Logs、Tabs、Ords是局部变量,仅在回调函数内部可访问,外部无法读取。 - 服务端代码中你将表格实例、工作表实例定义为全局变量,每次调用服务端函数时都会重新执行全局上下文,虽然不会直接报错,但存在上下文不稳定的隐患。
修复方案
1. 前端JS代码修改
把所有读取返回值、后续使用这三个数组的逻辑都放到withSuccessHandler绑定的回调函数内,或者将变量声明为全局作用域:
const inputs = document.querySelector('.dws-input'); const formControl = document.querySelectorAll('.form-control'); let findData; let curInpID; let firstValid, secValid, thirdValid, allValid; // 全局声明三个数组变量,方便后续其他逻辑调用 let Logs, Tabs, Ords; formControl[0].focus(); function callBack(e) { // 服务端返回结果后才执行这里的逻辑 Logs = e.ListLogins; Tabs = e.ListTables; Ords = e.ListOrders; // 打印要放到回调里才能拿到值 console.log(Logs); console.log(Tabs); console.log(Ords); // 后续需要用到这三个数组的逻辑也可以写在这里,或者调用其他函数传入这三个变量 } document.addEventListener("DOMContentLoaded", function(){ google.script.run.withSuccessHandler(callBack).sendData(); // 这里不要写读取返回值的逻辑,异步调用还没返回 });
2. 服务端代码优化(可选,建议修改)
将工作表相关的实例化逻辑放到sendData函数内,避免全局上下文带来的不可预期问题:
function doGet(e){ const htmlServ = HtmlService.createTemplateFromFile("index"); return htmlServ.evaluate(); } function include(filename){ return HtmlService.createHtmlOutputFromFile(filename).getContent(); } function sendData(){ const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheetTo = ss.getSheetByName("@sistem"); const sheetIn = ss.getSheetByName("@packing"); var lrLogins = sheetTo.getRange("A:A").getValues().filter(String).length; var arrLogins = sheetTo.getRange(1, 1, lrLogins, 1).getValues().flat(); var lrTMPLORDS = sheetTo.getRange("K:K").getValues().filter(String).length; var curTMPLORDS = sheetTo.getRange(1, 11, lrTMPLORDS, 1).getValues(); var lrTABLES = sheetTo.getRange("R:R").getValues().filter(String).length; var curTABLES = sheetTo.getRange(1, 18, lrTABLES, 1).getValues().flat(); var objDataInfo = {}; objDataInfo.ListLogins = arrLogins; objDataInfo.ListTables = curTABLES; objDataInfo.ListOrders = curTMPLORDS; return objDataInfo; }
修改完成后重新部署Web App即可在页面加载时正常获取到三个数组的内容。
内容的提问来源于stack exchange,提问作者Dmitriy Rudakov
相关产品推荐
相关产品推荐

