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.getSelectedDataAsync
Methoden , Binding.getDataAsync
oder 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.
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.Text
dass 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 desAsyncResult
-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 asyncContext
Eigenschaften , status
und 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 denresult
Parameter dieses Rückrufs zurückgegeben wird, ermöglicht den Zugriff auf das angegebene Bindungsobjekt über dieAsyncResult.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 dieBinding.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
, addFromPromptAsync
oder 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 AsyncResult
akzeptiert. 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
, addHandlerAsync
oder 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
, value1
usw. 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
Office Add-ins