是否可以在context.sync之前排队多个context.load?

时间:2017-06-09 13:52:20

标签: javascript ms-word office-js

我有一个Word的段落对象的段落对象。我有一些段落和关键字的索引的keywordRanges。我有另一组关键字,我想在文档中搜索并突出显示。

问题是 - 关键字搜索是线性的。我必须loadsync每个关键字的搜索结果。因此,如果一个关键字搜索需要大约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()

有可能吗?

1 个答案:

答案 0 :(得分:1)

是的,在一个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(免责声明,我是上述书的作者):我认为您可以在{{3}中的“使用Office.js构建Office加载项”一书中找到有关加载和批处理的大量有用信息。 }}。第5章 - 特别是关于Office.js的基础知识 - 目前包括以下章节,全部用于代理对象,加载和同步:

https://leanpub.com/buildingofficeaddins/