Excel JavaScript API 多.then()调用间变量传递报错解决问询
Excel JavaScript API 链式
.then()调用传递变量的解决方案 错误原因
你的代码报错是因为firstColumn变量仅定义在第一个.then()的回调函数作用域内,链式调用的后续.then()回调无法访问该作用域下的变量,因此抛出ReferenceError: firstColumn is not defined错误。
解决方案
以下是三种常用的实现方式,可根据你的编码习惯选择:
方式1:提升变量作用域
将需要跨.then()传递的变量定义在公共父作用域(也就是Excel.run传入的回调函数顶层),所有嵌套的.then()都可以访问该作用域下的变量。
Excel.run(function (context) { var currentWorksheet = context.workbook.worksheets.getActiveWorksheet(); var table = currentWorksheet.tables.getItem("NewTable"); // 提升变量到顶层作用域 var firstColumn; table.rows.load('count') return context.sync() .then(function () { var rowCount = table.rows.count; console.log("There are " + rowCount + " rows in the table."); // 直接给顶层变量赋值 firstColumn = table.columns.getItem(1); firstColumn.load("values"); return context.sync(); }) .then(function () { var firstColumnValues = firstColumn.values; var summary = {}; for (var i = 0; i < firstColumnValues.length; i++) { var value = firstColumnValues[i][0]; summary[value] = summary[value] ? summary[value] + 1 : 1; } console.log(summary); }) .catch(function (error) { console.log("Error: " + error); if (error instanceof OfficeExtension.Error) { console.log("Debug info: " + JSON.stringify(error.debugInfo)); } }); }) .catch(function (error) { console.log("Error: " + error); if (error instanceof OfficeExtension.Error) { console.log("Debug info: " + JSON.stringify(error.debugInfo)); } });
方式2:通过.then()返回值传递
前一个.then()回调的返回值会作为参数传入下一个.then()的回调,可通过该特性传递需要共享的变量。
Excel.run(function (context) { var currentWorksheet = context.workbook.worksheets.getActiveWorksheet(); var table = currentWorksheet.tables.getItem("NewTable"); table.rows.load('count') return context.sync() .then(function () { var rowCount = table.rows.count; console.log("There are " + rowCount + " rows in the table."); var firstColumn = table.columns.getItem(1); firstColumn.load("values"); // sync执行完成后返回firstColumn return context.sync().then(() => firstColumn); }) .then(function (firstColumn) { // 接收上一步返回的变量 var firstColumnValues = firstColumn.values; var summary = {}; for (var i = 0; i < firstColumnValues.length; i++) { var value = firstColumnValues[i][0]; summary[value] = summary[value] ? summary[value] + 1 : 1; } console.log(summary); }) .catch(function (error) { console.log("Error: " + error); if (error instanceof OfficeExtension.Error) { console.log("Debug info: " + JSON.stringify(error.debugInfo)); } }); }) .catch(function (error) { console.log("Error: " + error); if (error instanceof OfficeExtension.Error) { console.log("Debug info: " + JSON.stringify(error.debugInfo)); } });
方式3:改用async/await语法(更推荐)
async/await是ES2017引入的异步语法,可彻底避免链式.then()的作用域嵌套问题,代码可读性更高。
Excel.run(async function (context) { try { var currentWorksheet = context.workbook.worksheets.getActiveWorksheet(); var table = currentWorksheet.tables.getItem("NewTable"); table.rows.load('count') await context.sync(); var rowCount = table.rows.count; console.log("There are " + rowCount + " rows in the table."); var firstColumn = table.columns.getItem(1); firstColumn.load("values"); await context.sync(); var firstColumnValues = firstColumn.values; var summary = {}; for (var i = 0; i < firstColumnValues.length; i++) { var value = firstColumnValues[i][0]; summary[value] = summary[value] ? summary[value] + 1 : 1; } console.log(summary); } catch (error) { console.log("Error: " + error); if (error instanceof OfficeExtension.Error) { console.log("Debug info: " + JSON.stringify(error.debugInfo)); } } }) .catch(function (error) { console.log("Error: " + error); if (error instanceof OfficeExtension.Error) { console.log("Debug info: " + JSON.stringify(error.debugInfo)); } });
内容的提问来源于stack exchange,提问作者user2222943
相关产品推荐
相关产品推荐

