Freigeben über


Asynchrone Programmierung in Office-Add-Ins

Wichtig

Dieser Artikel bezieht sich auf die allgemeinen APIs, das Office JavaScript-API-Modell, das mit Office 2013 eingeführt wurde. Diese APIs enthalten Features wie z. B. Benutzeroberflächen, Dialogfelder und Clienteinstellungen, die in mehreren Office-Anwendungen enthalten sind. Outlook-Add-Ins verwenden ausschließlich allgemeine APIs, insbesondere die Teilmenge der APIs, die über das Postfach-Objekt verfügbar gemacht werden.

Sie sollten allgemeine APIs nur für Szenarien verwenden, die nicht von anwendungsspezifischen APIs unterstützt werden. Informationen dazu, wann Sie allgemeine APIs anstelle von anwendungsspezifischen APIs verwenden sollten, finden Sie unter Grundlegendes zur Office JavaScript-API.

Warum wird für die Office-Add-Ins-API asynchrone Programmierung verwendet? JavaScript ist eine Singlethreadsprache. Wenn ein Skript einen zeitintensiven synchronen Prozess des Office-Clients aufruft, werden alle nachfolgenden Skripts blockiert, bis dieser Prozess abgeschlossen ist. Wenn Sie asynchron sind, wird sichergestellt, dass Office-Add-Ins reaktionsfähig und schnell sind.

Die Namen aller asynchronen Methoden in den common-APIs enden mit "Async", z. B. den Document.getSelectedDataAsyncMethoden , Binding.getDataAsyncoder Item.loadCustomPropertiesAsync . Wenn eine "Async"-Methode aufgerufen wird, wird sie sofort ausgeführt. Der Rest des Skripts wird fortgesetzt, während der Vorgang auf clientseitiger Seite abgeschlossen wird. Die optionale Rückruffunktion, die Sie an eine "Async"-Methode übergeben, wird ausgeführt, sobald die Daten oder der angeforderte Vorgang bereit sind. Dies geschieht in der Regel sofort, aber es kann eine leichte Verzögerung geben.

Das folgende Diagramm zeigt den Fluss einer "Async"-Methode, die die Daten liest, die der Benutzer in einem Dokument ausgewählt hat. Wenn der "Async"-Aufruf erfolgt, kann der JavaScript-Thread alle zusätzlichen clientseitigen Verarbeitungen ausführen (obwohl keine im Diagramm dargestellt ist). Wenn die "Async"-Methode zurückgegeben wird, wird der Rückruf im Thread fortgesetzt. Das Add-In kann dann auf Daten zugreifen, etwas damit ausführen und das Ergebnis anzeigen. Das Muster ist plattformübergreifend identisch.

Diagramm, das die Interaktion der Befehlsausführung im Laufe der Zeit mit dem Benutzer, der Add-In-Seite und dem Web-App-Server zeigt, auf dem das Add-In gehostet wird.

Schreiben der Rückruffunktion für eine "Async"-Methode

Die Rückruffunktion, die Sie als Rückrufargument an eine "Async"-Methode übergeben, muss einen einzelnen Parameter deklarieren. Die Add-In-Runtime verwendet diesen Parameter, um zugriff auf ein AsyncResult-Objekt für die Rückruffunktion bereitzustellen.

Die Rückruffunktion kann entweder eine anonyme Funktion oder eine benannte Funktion sein. Eine anonyme Funktion ist nützlich, wenn Sie ihren Code nur einmal verwenden möchten. Da sie keinen Namen hat, können Sie nicht in einem anderen Teil Ihres Codes darauf verweisen. Eine benannte Funktion ist nützlich, wenn Sie die Rückruffunktion für mehr als eine "Async"-Methode wiederverwenden möchten.

Schreiben einer anonymen Rückruffunktion

Die folgende anonyme Rückruffunktion deklariert einen einzelnen Parameter namens result für die vom Client zurückgegebenen Daten. Sie ruft diese Daten ab und schreibt sie aus der Eigenschaft AsyncResult.value , wenn der Rückruf zurückgibt.

function (result) {
    write('Selected data: ' + result.value);
}

Das folgende Beispiel zeigt diese anonyme Rückruffunktion im Kontext eines vollständigen "Async"-Methodenaufrufs der Document.getSelectedDataAsync(coercionType, callback) -Methode.

  • Das erste coercionType-Argument gibt an, Office.CoercionType.Textdass die ausgewählten Daten als Textzeichenfolge zurückgegeben werden sollen.

  • Das zweite Rückrufargument ist die anonyme Funktion, die inline an die -Methode übergeben wird. Wenn die Funktion ausgeführt wird, wird der Result-Parameter verwendet, um auf die value -Eigenschaft des AsyncResult -Objekts zuzugreifen. Anschließend werden die vom Benutzer im Dokument ausgewählten Daten angezeigt.

Office.context.document.getSelectedDataAsync(Office.CoercionType.Text, 
    function (result) {
        write('Selected data: ' + result.value);
    }
});

// Function that writes to a div with id='message' on the page.
function write(message){
    document.getElementById('message').innerText += message; 
}

Sie können auch den Parameter Ihrer Rückruffunktion verwenden, um auf andere Eigenschaften des AsyncResult Objekts zuzugreifen. Verwenden Sie die AsyncResult.status-Eigenschaft, um zu bestimmen, ob der Aufruf erfolgreich ausgeführt wurde oder ob ein Fehler aufgetreten ist. Wenn der Aufruf fehlgeschlagen ist, verwenden Sie die Eigenschaft AsyncResult.error , um auf ein Error-Objekt zuzugreifen, um zu entscheiden, was zu tun ist.

Weitere Informationen zur getSelectedDataAsync -Methode finden Sie unter Lesen und Schreiben von Daten in die aktive Auswahl in einem Dokument oder arbeitsblatt.

Schreiben einer benannten Rückruffunktion

Alternativ können Sie eine benannte Funktion schreiben und ihren Namen an den Rückrufparameter einer "Async"-Methode übergeben. Hier wird das vorherige Beispiel so umgeschrieben, dass eine Funktion mit dem Namen writeDataCallback als Rückrufparameter übergeben wird.

Office.context.document.getSelectedDataAsync(Office.CoercionType.Text, 
    writeDataCallback);

// Callback to write the selected data to the add-in UI.
function writeDataCallback(result) {
    write('Selected data: ' + result.value);
}

// Function that writes to a div with id='message' on the page.
function write(message){
    document.getElementById('message').innerText += message;
}

Unterschiede in der Rückgabe an die AsyncResult.value Eigenschaft

Die asyncContextEigenschaften , statusund error des AsyncResult -Objekts geben die gleichen Arten von Informationen an die Rückruffunktionen zurück, die an alle "Async"-Methoden übergeben werden. Was an die AsyncResult.value -Eigenschaft zurückgegeben wird, hängt jedoch von der Funktionalität der "Async"-Methode ab.

Beispielsweise werden die addHandlerAsync Methoden (der Objekte Binding, CustomXmlPart, Document, RoamingSettings und Settings ) verwendet, um Ereignishandlerfunktionen hinzuzufügen. Die AsyncResult.value -Eigenschaft in diesen Rückruffunktionen gibt immer undefiniert zurück, da beim Hinzufügen eines Ereignishandlers auf keine Daten oder Objekte zugegriffen wird.

Wenn Sie hingegen die Document.getSelectedDataAsync -Methode aufrufen, werden die Daten zurückgegeben, die der Benutzer im Dokument als AsyncResult.value Eigenschaft im Rückruf ausgewählt hat. Wenn Sie die Bindings.getAllAsync-Methode aufrufen, wird ein Array aller Binding Objekte im Dokument zurückgegeben.

Eine Beschreibung dessen, was an die AsyncResult.value -Eigenschaft für eine Async Methode zurückgegeben wird, finden Sie im callback Abschnitt des Referenzthemas dieser Methode.

Asynchrone Programmiermuster

Die allgemeinen APIs in der Office JavaScript-API unterstützen zwei Arten von asynchronen Programmiermustern.

  • Geschachtelte Rückrufe
  • Verspricht

Hinweis

In der aktuellen Version der Office JavaScript-API funktioniert die integrierte Unterstützung für das Zusagenmuster nur mit Code für Bindungen in Excel-Tabellen und Word Dokumenten. Sie können jedoch andere Funktionen mit Rückrufen in Ihrer eigenen benutzerdefinierten Promise-returning-Funktion umschließen. Weitere Informationen finden Sie unter Wrap Common APIs in Promise-Returning functions (Umschließen allgemeiner APIs in Funktionen zur Rückgabe von Zusagen).

Asynchrone Programmierung mithilfe geschachtelter Rückruffunktionen

Häufig müssen Sie für eine Aufgabe mehrere asynchrone Vorgänge ausführen. Zu diesem Zweck können Sie einen "Async"-Aufruf in einen anderen "Async"-Aufruf schachteln.

Im folgenden Codebeispiel werden zwei asynchrone Aufrufe geschachtelt.

  • Zunächst wird die Bindings.getByIdAsync-Methode aufgerufen, um auf die Bindung „MyBinding“ im Dokument zuzugreifen. Das AsyncResult -Objekt, das an den result Parameter dieses Rückrufs zurückgegeben wird, ermöglicht den Zugriff auf das angegebene Bindungsobjekt über die AsyncResult.value -Eigenschaft.
  • Anschließend wird das Bindungsobjekt, auf das über den ersten result Parameter zugegriffen wird, verwendet, um die Binding.getDataAsync-Methode aufzurufen.
  • Schließlich wird der result2 -Parameter des An die Binding.getDataAsync -Methode übergebenen Rückrufs verwendet, um die Daten in der Bindung anzuzeigen.
function readData() {
    Office.context.document.bindings.getByIdAsync("MyBinding", function (result) {
        result.value.getDataAsync({ coercionType: 'text' }, function (result2) {
            write(result2.value);
        });
    });
}

// Function that writes to a div with id='message' on the page.
function write(message){
    document.getElementById('message').innerText += message; 
}

Dieses grundlegende geschachtelte Rückrufmuster kann für alle asynchronen Methoden in den allgemeinen APIs verwendet werden.

Asynchrone Programmierung mithilfe des Zusagemusters zum Zugriff auf Daten in Bindungen

Anstatt eine Rückruffunktion zu übergeben und darauf zu warten, dass die Funktion zurückgegeben wird, bevor das Skript fortgesetzt wird, gibt das Zusagen-Programmiermuster sofort ein Promise -Objekt zurück, das das beabsichtigte Ergebnis darstellt. Anders als bei der tatsächlichen synchronen Programmierung wird die Erfüllung des versprochenen Ergebnisses jedoch tatsächlich zurückgestellt, bis die Office-Add-Ins-Laufzeitumgebung die Anforderung abgeschlossen hat. Es wird ein onError-Handler für den Fall bereitgestellt, dass die Anforderung nicht erfüllt werden kann.

Die allgemeinen APIs stellen die Office.select-Funktion bereit, um das Zusagenmuster bei der Arbeit mit vorhandenen Bindungsobjekten zu unterstützen. Das an die Office.select Funktion zurückgegebene Zusageobjekt unterstützt nur die vier Methoden, auf die direkt über das Binding-Objekt zugegriffen werden kann.

Das Zusagenmuster für die Arbeit mit Bindungen hat diese Form.

Office.select( selectorExpression,onError).BindingObjectAsyncMethod;

Der SelectorExpression-Parameter hat das Format "bindings#bindingId", wobei bindingId der Name ( id) einer Bindung ist, die Sie im Dokument oder arbeitsblatt erstellt haben (mit einer der "addFrom"-Methoden der Bindings Auflistung: addFromNamedItemAsync, addFromPromptAsyncoder addFromSelectionAsync). Die BeispielauswahlExpression von bindings#cities gibt an, dass Sie auf die Bindung mit der ID "cities" zugreifen möchten.

Der onError-Parameter ist eine Fehlerbehandlungsfunktion, die einen einzelnen Parameter vom Typ AsyncResultakzeptiert. Dies wird verwendet, um auf ein Error Objekt zuzugreifen, wenn die select Funktion nicht auf die angegebene Bindung zugreifen kann. Das folgende Beispiel zeigt eine einfache Fehlerhandlerfunktion, die an den onError-Parameter übergeben werden kann.

function onError(result){
    const err = result.error;
    write(err.name + ": " + err.message);
}

// Function that writes to a div with id='message' on the page.
function write(message){
    document.getElementById('message').innerText += message; 
}

Ersetzen Sie den Platzhalter BindingObjectAsyncMethod durch einen Aufruf einer der vier Binding Objektmethoden, die vom Zusageobjekt unterstützt werden: getDataAsync, setDataAsync, addHandlerAsyncoder removeHandlerAsync. Aufrufe dieser Methoden unterstützen keine weiteren Zusagen. In diesem Fall müssen Sie das Geschachtelte Rückruffunktionsmuster verwenden.

Nachdem eine Binding Objektzusage erfüllt wurde, kann sie im verketteten Methodenaufruf wiederverwendet werden, als wäre es eine Bindung. Wenn dies erfolgreich ist, versucht die Add-In-Runtime nicht asynchron, die Zusage zu erfüllen. Wenn die Binding Objektzusage nicht erfüllt werden kann, versucht die Add-In-Runtime erneut, auf das Bindungsobjekt zuzugreifen, wenn das nächste Mal eine ihrer asynchronen Methoden aufgerufen wird.

Im folgenden Beispiel wird die select -Funktion verwendet, um eine Bindung mit dem id "cities" aus der Bindings Auflistung abzurufen. Anschließend wird die addHandlerAsync-Methode aufgerufen, um einen Ereignishandler für das dataChanged-Ereignis der Bindung hinzuzufügen.

function addBindingDataChangedEventHandler() {
    Office.select("bindings#cities", function onError(){/* error handling code */}).addHandlerAsync(Office.EventType.BindingDataChanged,
    function (eventArgs) {
        doSomethingWithBinding(eventArgs.binding);
    });
}

Wichtig

Die Binding von der Office.select Funktion zurückgegebene Objektzusage bietet nur Zugriff auf die vier Methoden des Binding Objekts. Wenn Sie auf einen der anderen Member des Binding Objekts zugreifen müssen, müssen Sie stattdessen die Document.bindings -Eigenschaft und Bindings.getByIdAsync oder Bindings.getAllAsync -Methode verwenden, um das Binding Objekt abzurufen.

Übergeben optionaler Parameter an asynchrone Methoden

Die allgemeine Syntax für alle "Async"-Methoden folgt diesem Muster.

asyncMethod(requiredParameters, [optionalParameters],callbackFunction);

Alle asynchronen Methoden unterstützen optionale Parameter. Diese werden als JavaScript-Objekt übergeben. Das Objekt, das die optionalen Parameter enthält, ist eine ungeordnete Auflistung von Schlüssel-Wert-Paaren. Sie können das Objekt, das optionale Parameter enthält, inline erstellen, oder indem Sie ein options -Objekt erstellen und dieses als options-Parameter übergeben.

Übergeben optionaler Parameter inline

Hier sehen Sie ein Beispiel für die Document.setSelectedDataAsync-Methode mit optionalen Parametern, die inline definiert sind. Die beiden optionalen Parameter coercionType und asyncContext werden als anonymes JavaScript-Objekt definiert.

Office.context.document.setSelectedDataAsync(
    "<html><body>hello world</body></html>",
    {coercionType: "html", asyncContext: 42},
    function(asyncResult) {
        write(asyncResult.status + " " + asyncResult.asyncContext);
    }
)

// Function that writes to a div with id='message' on the page.
function write(message){
    document.getElementById('message').innerText += message; 
}

Übergeben optionaler Parameter in einem benannten Objekt

Alternativ können Sie ein benanntes Objekt erstellen, das die optionalen Parameter getrennt vom Methodenaufruf angibt, und dann das Objekt als Optionsargument übergeben. Das folgende Beispiel zeigt eine Möglichkeit zum Erstellen eines options Objekts, wobei parameter1, value1usw. Platzhalter für die tatsächlichen Parameternamen und -werte sind.

const options = {
    parameter1: value1,
    parameter2: value2,
    ...
    parameterN: valueN
};

Dieses sieht wie im folgenden Beispiel aus, wenn es zum Angeben der Parameter ValueFormat und FilterType verwendet wird:

const options = {
    valueFormat: "unformatted",
    filterType: "all"
};

Hier ist eine weitere Möglichkeit zum Erstellen des options -Objekts.

const options = {};
options[parameter1] = value1;
options[parameter2] = value2;
...
options[parameterN] = valueN;

Dies sieht wie im folgenden Beispiel aus, wenn die Parameter und FilterType angegeben ValueFormat werden:

const options = {};
options["ValueFormat"] = "unformatted";
options["FilterType"] = "all";

Das folgende Beispiel zeigt, wie Sie die Document.setSelectedDataAsync -Methode aufrufen, indem Sie optionale Parameter in einem options -Objekt angeben.

const options = {
   coercionType: "html",
   asyncContext: 42
};

document.setSelectedDataAsync(
    "<html><body>hello world</body></html>",
    options,
    function(asyncResult) {
        write(asyncResult.status + " " + asyncResult.asyncContext);
    }
)

// Function that writes to a div with id='message' on the page.
function write(message){
    document.getElementById('message').innerText += message; 
}

In beiden Beispielen für optionale Parameter wird der Rückrufparameter als letzter Parameter angegeben (nach den optionalen Inlineparametern oder nach dem Optionsargumentobjekt ). Alternativ können Sie den Rückrufparameter entweder innerhalb des JavaScript-Inlineobjekts oder im options -Objekt angeben. Sie können den Rückrufparameter jedoch nur an einer Stelle übergeben: entweder im options -Objekt (inline oder extern erstellt) oder als letzter Parameter, aber nicht beides.

Umschließen allgemeiner APIs in Promise-returning-Funktionen

Die Allgemeinen API-Methoden (und Outlook-API) geben keine Zusagen zurück. Daher können Sie await nicht verwenden, um die Ausführung anzuhalten, bis der asynchrone Vorgang abgeschlossen ist. Wenn Sie Verhalten benötigen await , umschließen Sie den Methodenaufruf in einem explizit erstellten Promise.

Das grundlegende Muster besteht darin, eine asynchrone Methode zu erstellen, die sofort ein Promise-Objekt zurückgibt und dieses Promise-Objekt auflöst , wenn die innere Methode abgeschlossen ist, oder das Objekt ablehnt , wenn die Methode fehlschlägt. Nachfolgend sehen Sie ein einfaches Beispiel.

function getDocumentFilePath() {
    return new OfficeExtension.Promise(function (resolve, reject) {
        try {
            Office.context.document.getFilePropertiesAsync(function (asyncResult) {
                resolve(asyncResult.value.url);
            });
        }
        catch (error) {
            reject(WordMarkdownConversion.errorHandler(error));
        }
    })
}

Wenn diese Funktion gewartet werden muss, kann sie entweder mit dem await Schlüsselwort (keyword) aufgerufen oder an eine then Funktion übergeben werden.

Hinweis

Dieses Verfahren ist besonders nützlich, wenn Sie eine allgemeine API innerhalb eines Aufrufs der run Funktion in einem anwendungsspezifischen Objektmodell aufrufen müssen. Ein Beispiel für die Funktion, die getDocumentFilePath auf diese Weise verwendet wird, finden Sie in der DateiHome.js im Beispiel Word-Add-in-JavaScript-MDConversion.

Siehe auch