使用异步执行上下文为 Office.js Javascript Word 加载项添加子例程



我在开发 Office .js Word 加载项方面取得了很大的成功。外接程序的常见任务之一是搜索和替换,这需要由外接程序中的多个操作按钮使用。因此,我想创建一个函数,将搜索和替换任务分开,这样我就可以避免错误并使代码更加模块化。我在尝试使用 Office.js 异步执行模型执行此操作时陷入困境。

此代码有效(作为 React 类的方法(:

replaceX() {
console.log("replaceX");
window.Word.run(async (context: any) => {
const range = context.document.getSelection();
await context.sync();
var query = "X";
var replacement = "gabagool";
var results = range.search(query);
results.load();               
await context.sync();
for (var i=0; i<results.items.length; i++) {
results.items[i].insertText(replacement,'Replace');
}
await context.sync();
});
}

但是此代码失败:

replaceX() {
console.log("replaceX");
window.Word.run(async (context: any) => {
const range = context.document.getSelection();
await context.sync();
var query = "X";
var replacement = "gabagool";
this.replaceInRange(context, range, query, replacement, {});
await context.sync();
});
}
async replaceInRange(context:any, range:any, query:String, replacement:String, searchOptions:any) {
console.log('replaceInRange');
var results = range.search(query, searchOptions);
results.load();
await context.sync();
for (var i=0; i<results.items.length; i++) {
results.items[i].insertText(replacement,'Replace');
}
}

我已经尝试了一些变化,但我确定我错过了一些基本的东西。谁能帮我找出处理需要访问父函数上下文的子例程的正确方法?

你的代码正在破坏承诺链。您的replaceInRange方法中有一个异步调用来context.sync,但replaceInRange本身并没有等待,因此一旦它开始执行,执行引擎就会移动到调用replaceInRange下方的行,这是另一个context.sync。但是最后一个context.sync将在字符串替换代码运行之前完成,然后Word.run将完成。

尝试在调用replaceInRange前面放置一个await关键字,如下所示:

await this.replaceInRange(context, range, query, replacement, {});

我注意到的其他几件事:

  1. 不需要Word.run中的第一个context.sync

  2. 您不会将任何参数传递给load()方法。执行此操作时,将加载所有标量属性。这是不必要的性能影响。您只需要加载text属性即可执行insertText。使用results.load('text');

  3. Word.run本身是异步的,因此在调用它时可能应该使用await关键字。您可以在没有await的情况下逃脱,因为您的父方法在 Word.run 执行后不调用任何内容,但是如果您曾经修改过该方法以便在Word.run之后调用更多内容,如果您不等待Word.run,则在Word.run完成之前将开始执行更多内容。

有一本关于 Office 外接程序的好书,其中包含有关这些主题的大量信息,包括承诺链:构建 Office 外接程序。它花费了一些东西,但这是值得的。在你问之前,这不是我的书,我从它的销售中没有任何收获。

最新更新