我尝试为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');
}
}
我尝试了一些变体,但我确信我遗漏了一些基本的东西。谁能帮我找出正确的方法来处理需要访问父函数上下文的子例程?
发布于 2018-06-04 00:19:00
您的代码正在破坏承诺链。您的replaceInRange
方法内部有一个对context.sync
的异步调用,但replaceInRange
本身并不等待,因此一旦它开始执行,执行引擎就会移到replaceInRange
调用下面的行,这是另一个context.sync
。但是,在字符串替换代码运行之前,最后一个context.sync
将完成,然后Word.run
将完成。
尝试将await
关键字放在调用replaceInRange
的前面,如下所示:
await this.replaceInRange(context, range, query, replacement, {});
我还注意到了其他几件事:
Word.run
中的第一个context.sync
。load()
方法传递任何参数。执行此操作时,将加载所有标量属性。这是一个不必要的性能损失。您只需加载text
属性即可执行insertText
。使用results.load('text');
Word.run
本身就是异步的,因此在调用它时可能应该使用await
关键字。不使用await
也可以避免这种情况,因为父方法在Word.run执行之后什么也不调用,但是如果您曾经修改过该方法,以便在Word.run
之后调用更多的东西,那么如果您不等待Word.run
,那么在Word.run
完成之前就会执行更多的东西有一本关于Office add-ins的好书,里面有很多关于这些主题的信息,包括Promise chains:Building Office Add-ins。它花费了一些钱,但它是值得的。在你问之前,这不是我的书,我也没有从它的销售中获得任何好处。
https://stackoverflow.com/questions/50668175
复制相似问题