Mit Typescript 2.1 wurde die lange erwartete Spracherweiterung für asynchrone Programmierung implementiert. Dem C# Entwickler sind die Schlüsselwörter async und await bekannt. Nun können diese auch in TypeScript Anwendungen verwendet werden.
Wie TypeScript in SharePoint-Hosted Apps verwendet werden kann habe ich in einem früheren Artikel gezeigt. Aber um async und await zu nutzen, muss dies dem TypeScript Compiler mitgeteilt werden. Im Visual Studio Projekt File muss bei den beiden Property Groups (für Debug und Release) noch die folgende Zeile eingefügt werden:
<TypeScriptLib>DOM,es2015.promise,es5</TypeScriptLib>
Diese Zeile bewirkt, dass in TypeScript Funktionen implementiert werden können, die ein Promise Objekt zurückliefern. Die grundsätzliche Verwendung von Promise habe ich vor langer Zeit, also weit vor TypeScript 2.1, hier gezeigt. Promise wird von Google Chrome direkt unterstützt. Soll unser Code in einem Internet Explorer laufen, so müssen wir selbst ein Promise-Objekt implementieren. Zum Glück haben das bereits andere übernommen. Ich habe die Bibliothek “Bluebird.js” im Einsatz (siehe: bluebirdjs.com)
Promise im Einsatz
Nachdem der Compiler konfiguriert ist, und die Bluebird-Bibliothek eingebunden ist, können wir beginnen eine Klasse zu schreiben. Ich möchte ich dieser Klasse den Zugriff auf Documentbibliotheken kapseln und erstelle eine Funktion die ein Array<string> mit allen Listen-Titel liefert die nicht “versteckt” sind. Die Klasse mit der Funktion “getDocLibs” ist hier zu sehen:
class SPDocTemplates {
public getDocLibs() {
return new Promise<Array<string>>((resolve, reject) => {
var h = new SPHelper();
var lists = h.hostCTX.get_web().get_lists();
h.clientCTX.load(lists, 'Include(Title,Hidden)');
h.clientCTX.executeQueryAsync(
() => {
var ret = new Array<string>();
var enumerator = lists.getEnumerator();
while (enumerator.moveNext()) {
var list = enumerator.get_current();
var title = list.get_title();
if(list.get_hidden()==false)
ret.push(title);
}
resolve(ret);
},
(sender,args) => {
reject(args.get_message());
});
});
}
}
Die Methode liefert ein Promise Objekt zurück. Dieses wird im return gleich initialisiert und im Konstruktur wird eine anonyme Funktion definiert, die die Methoden für resolve und reject übergeben bekommt. Innerhalb der anonymen Funktion wird mit dem CSOM auf die Bibliotheken zugegriffen.
Es wird das Array mit den Listentiteln aufgebaut. Sobald dieses fertig ist, wird die Methode resolve aufgerufen und das Array übergeben.
Sollte ein Fehler aufgetreten sein, wird die Methode reject aufgerufen.
Async Await
Bisher ist noch kein Vorteil zu erkennen. Aber nun kommt der Auftritt von async/await…
Wir können nun die zuvor erstellte Klasse verwenden:
async function Start() {
var d = new SPDocTemplates();
try {
var l = await d.getDocLibs();
}
catch (err){
alert(err);
}
l.forEach((titel) => {
$('#bibs').append('<li><a href="#">' + titel + '</a></li>');
});
}
Die Funktion wird mit dem Schlüsselwort async definiert. Das ist notwendig, wenn innerhalb der Funktion mit await gearbeitet wird. Vor dem Aufruf der Funktion “getDocLibs” wird das Schlüsselwort await gesetzt. Um einen Fehlerfall auswerten zu können, wird der gesamte Aufruf in ein try-catch verpackt.
Fazit
Mit Async/Await ist es nun möglich die Ansynchronität des CSOM zu nutzen, die Zugriffe auf SharePoint in Klassen zu verpacken und dennoch den Code übersichtlich zu gestalten.