是否可以在 context.sync 之前排队超过一个 context.load?
Is it possible to queue more than one context.load before context.sync?
我有一个 Word 段落对象的 paragraphObjects。我有一些段落和关键字索引的关键字范围。我还有一组要在文档中搜索和突出显示的关键字。
问题是 - 关键字搜索是线性的。我要load
和sync
每个关键字的搜索结果。因此,如果一次关键字搜索需要约 300 毫秒,则搜索 15 次将需要约 4500 秒。我想并行执行所有关键字搜索加载同步操作,所以我在 ~300 毫秒内得到所有结果,与关键字数组的大小无关。
代码示例如下:
let paragraphObjects = []
let keywordsObject = {
"2": {
"keywords": ["the", "which", "eye"]
},
"4": {
"keywords": ["lorem", "ipsum"]
},
"9": {
"keywords": ["hellow", "world", "foo", "bar"]
}
}
let keywordRanges = []
let searchKeywordResults = []
Word.run((context) => {
var paragraphs = context.document.body.paragraphs
context.load(paragraphs, 'text, font, style');
return context.sync().then(() => {
for (var i = 0; i < paragraphs.items.length; i++) {
paragraphObjects.push(paragraphs.items[i])
}
$.each(keywordsObject, (divId, divValue) => {
$.each(divValue.keywords, (idx, keyword) => {
var obj = { paragraphObject: pa[currentParaIndex], keyword: keyword }
keywordRanges.push(obj)
})
})
})
.then(() => {
if (keywordRanges.length > 0) {
$.each(keywordRanges, (idx, obj) => {
var paragraphObject = obj.paragraphObject
var keyword = obj.keyword
searchKeywordResults[idx] = paragraphObject.search(keyword, { matchWholeWord: true })
})
let highlight = async() => {
for (let i = 0; i < searchKeywordResults.length; i++) {
context.load(searchKeywordResults[i], 'text, font')
await context.sync() // each iteration takes around 300 milliseconds.
}
for (let i = 0; i < searchKeywordResults.length; i++) {
for (let j = 0; j < searchKeywordResults[i].items.length; j++) {
searchKeywordResults[i].items[j].font.highlightColor = highlightColorValue
}
}
await context.sync()
return
}
highlight()
}
})
})
我想用
替换此代码
for (let i = 0; i < searchKeywordResults.length; i++) {
context.load(searchKeywordResults[i], 'text, font')
await context.sync()
}
有了这个
for (let i = 0; i < searchKeywordResults.length; i++) {
context.load(searchKeywordResults[i], 'text, font')
}
await context.sync()
可能吗?
是的,将多个操作排队 sync
是 Office 2016+ API 批处理模型的重要组成部分。
举个很简单的Excel例子:
async function run() {
try {
await Excel.run(async (context) => {
let sheet = context.workbook.worksheets.getItem("Sheet1");
let a1 = sheet.getRange("A1");
let b2 = sheet.getRange("B2");
let c3 = sheet.getRange("C3");
[a1, b2, c3].forEach(range => range.load("values"));
await context.sync();
[a1, b2, c3].forEach(range => console.log(range.values[0][0]));
});
}
catch (error) {
OfficeHelpers.UI.notify(error);
OfficeHelpers.Utilities.log(error);
}
}
所以,它绝对应该有效。当您尝试这样的操作时是否遇到错误?
FWIW(免责声明,我是该书的作者):我想您会在 "Building Office Add-in using Office.js" 一书中找到很多关于加载和批处理的有用信息,可在 https://leanpub.com/buildingofficeaddins/ 找到。特别是第 5 章——关于 Office.js 的基础知识——目前包括以下章节,全部用于代理对象、加载和同步:
我有一个 Word 段落对象的 paragraphObjects。我有一些段落和关键字索引的关键字范围。我还有一组要在文档中搜索和突出显示的关键字。
问题是 - 关键字搜索是线性的。我要load
和sync
每个关键字的搜索结果。因此,如果一次关键字搜索需要约 300 毫秒,则搜索 15 次将需要约 4500 秒。我想并行执行所有关键字搜索加载同步操作,所以我在 ~300 毫秒内得到所有结果,与关键字数组的大小无关。
代码示例如下:
let paragraphObjects = []
let keywordsObject = {
"2": {
"keywords": ["the", "which", "eye"]
},
"4": {
"keywords": ["lorem", "ipsum"]
},
"9": {
"keywords": ["hellow", "world", "foo", "bar"]
}
}
let keywordRanges = []
let searchKeywordResults = []
Word.run((context) => {
var paragraphs = context.document.body.paragraphs
context.load(paragraphs, 'text, font, style');
return context.sync().then(() => {
for (var i = 0; i < paragraphs.items.length; i++) {
paragraphObjects.push(paragraphs.items[i])
}
$.each(keywordsObject, (divId, divValue) => {
$.each(divValue.keywords, (idx, keyword) => {
var obj = { paragraphObject: pa[currentParaIndex], keyword: keyword }
keywordRanges.push(obj)
})
})
})
.then(() => {
if (keywordRanges.length > 0) {
$.each(keywordRanges, (idx, obj) => {
var paragraphObject = obj.paragraphObject
var keyword = obj.keyword
searchKeywordResults[idx] = paragraphObject.search(keyword, { matchWholeWord: true })
})
let highlight = async() => {
for (let i = 0; i < searchKeywordResults.length; i++) {
context.load(searchKeywordResults[i], 'text, font')
await context.sync() // each iteration takes around 300 milliseconds.
}
for (let i = 0; i < searchKeywordResults.length; i++) {
for (let j = 0; j < searchKeywordResults[i].items.length; j++) {
searchKeywordResults[i].items[j].font.highlightColor = highlightColorValue
}
}
await context.sync()
return
}
highlight()
}
})
})
我想用
替换此代码for (let i = 0; i < searchKeywordResults.length; i++) {
context.load(searchKeywordResults[i], 'text, font')
await context.sync()
}
有了这个
for (let i = 0; i < searchKeywordResults.length; i++) {
context.load(searchKeywordResults[i], 'text, font')
}
await context.sync()
可能吗?
是的,将多个操作排队 sync
是 Office 2016+ API 批处理模型的重要组成部分。
举个很简单的Excel例子:
async function run() {
try {
await Excel.run(async (context) => {
let sheet = context.workbook.worksheets.getItem("Sheet1");
let a1 = sheet.getRange("A1");
let b2 = sheet.getRange("B2");
let c3 = sheet.getRange("C3");
[a1, b2, c3].forEach(range => range.load("values"));
await context.sync();
[a1, b2, c3].forEach(range => console.log(range.values[0][0]));
});
}
catch (error) {
OfficeHelpers.UI.notify(error);
OfficeHelpers.Utilities.log(error);
}
}
所以,它绝对应该有效。当您尝试这样的操作时是否遇到错误?
FWIW(免责声明,我是该书的作者):我想您会在 "Building Office Add-in using Office.js" 一书中找到很多关于加载和批处理的有用信息,可在 https://leanpub.com/buildingofficeaddins/ 找到。特别是第 5 章——关于 Office.js 的基础知识——目前包括以下章节,全部用于代理对象、加载和同步: