Добавьте подпрограмму для надстройки Word Javascript Office.js, используя контекст асинхронного выполнения - PullRequest
0 голосов
/ 03 июня 2018

Я добился больших успехов в разработке надстройки 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');
    }

}

Я пробовал несколько вариантов, но я уверен, что упускаю что-то фундаментальное.Может кто-нибудь помочь мне выяснить правильный способ обработки подпрограммы, которая должна получить доступ к контексту родительской функции?

1 Ответ

0 голосов
/ 03 июня 2018

Ваш код нарушает цепочку обещаний.Ваш replaceInRange метод имеет асинхронный вызов внутри context.sync, но replaceInRange сам по себе не ожидается, поэтому, как только он начинает выполняться, механизм выполнения переходит к строке под вызовом replaceInRange,что другое context.sync.Но этот последний context.sync завершится, а затем Word.run завершится, прежде чем будет выполнен код замены строки.

Попробуйте поставить ключевое слово await перед вызовом replaceInRange следующим образом:

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

Я заметил еще пару вещей:

  1. Самый первый context.sync в вашем Word.run не нужен.

  2. Вы не передаете никаких параметров методу load().Когда вы делаете это, все скалярные свойства загружаются.Это ненужный удар по производительности.Вам нужно только загрузить свойство text, чтобы сделать insertText.Использование results.load('text');

  3. Word.run само по себе является асинхронным, поэтому вам, вероятно, следует использовать ключевое слово await при его вызове.Вы можете уйти, не имея await, потому что ваш родительский метод ничего не вызывает после выполнения Word.run, но если вы когда-нибудь изменили метод так, чтобы после Word.run вызывалось что-то большее, то что-то большее начало выполняться до Word.run было завершено, если вы не ожидаете Word.run.

Существует хорошая книга об надстройках Office, в которой содержится много информации по этим предметам, включая цепочки Promise: Здание Office Надстройки .Это чего-то стоит, но оно того стоит.Прежде чем спросить, это не моя книга, и я ничего не получу от ее продажи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...