我已经投入了大量精力开发针对Word的Office.js加载项。外接程序的常见任务之一是搜索和替换,该操作需要由外接程序中的多个操作按钮使用。因此,我想创建一个将搜索和替换任务分开的函数,这样我就可以避免错误并使代码更具模块化。我陷入尝试使用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');
}
}
我尝试了一些变体,但是我确定我缺少基本的东西。谁能帮助我找出正确的方法来处理需要访问父函数上下文的子例程?
您的代码打破了Promise链。您的replaceInRange
方法中有一个对的异步调用context.sync
,但replaceInRange
自身尚未等待,因此,一旦方法开始执行,执行引擎就会移至对to的调用之下的replaceInRange
另一行context.sync
。但是在字符串替换代码运行之前context.sync
,这最后一个将完成,然后Word.run
将完成。
尝试将await
关键字放在呼叫之前,replaceInRange
如下所示:
await this.replaceInRange(context, range, query, replacement, {});
我注意到了其他几件事:
不需要context.sync
您中的第一个Word.run
。
您没有向该load()
方法传递任何参数。执行此操作时,将加载所有标量属性。这是不必要的性能损失。您只需要加载该text
属性即可执行insertText
。使用results.load('text');
Word.run
本身是异步的,因此await
在调用它时可能应该使用关键字。您可以不必逃避,await
因为在Word.run执行之后您的父方法没有调用任何东西,但是如果您曾经修改过该方法,以便在之后调用Word.run
更多的东西,那么Word.run
如果您不执行该操作,那么其他东西会在完成之前开始执行等待Word.run
。
关于Office加载项的书很好,其中有很多关于这些主题的信息,包括Promise链:构建Office加载项。它花了一些钱,但值得。在您问之前,这不是我的书,我从书中得不到任何收益。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句