Async / Warten auf Klassenkonstruktor

10

Momentan versuche ich async/await innerhalb einer Klassenkonstruktorfunktion zu verwenden. Dies ist so, dass ich ein benutzerdefiniertes e-mail -Tag für ein Electron-Projekt bekommen kann, an dem ich gerade arbeite.

%Vor%

Im Moment funktioniert das Projekt jedoch nicht, mit dem folgenden Fehler:

%Vor%

Gibt es eine Möglichkeit, dies zu umgehen, damit ich async / abwarten kann? Statt Callbacks oder .then ()?

zu erfordern     
Popey Gilbert 15.04.2017, 21:41
quelle

5 Antworten

31

Dies kann nie funktionieren.

Das async Schlüsselwort erlaubt await in einer Funktion zu verwenden, die als async markiert ist, aber es konvertiert diese Funktion auch in einen Versprechensgenerator. Eine Funktion, die mit async markiert ist, gibt also ein Versprechen zurück. Ein Konstruktor hingegen gibt das Objekt zurück, das er konstruiert. Somit haben wir eine Situation, in der Sie sowohl ein Objekt als auch ein Versprechen zurückgeben wollen: eine unmögliche Situation.

Sie können nur async verwenden / erwarten, wo Sie Versprechungen verwenden können, weil sie im Wesentlichen Syntax Zucker für Versprechen sind. Sie können Versprechungen in einem Konstruktor nicht verwenden, da ein Konstruktor das zu erstellende Objekt zurückgeben muss, kein Versprechen.

Es gibt zwei Entwurfsmuster, um dies zu überwinden, beide erfunden, bevor Versprechen gegeben wurden.

  1. Verwendung einer init() -Funktion. Das funktioniert ein wenig wie jQuerys .ready() . Das von Ihnen erstellte Objekt kann nur innerhalb seiner eigenen Funktion init oder ready verwendet werden:

    Verwendung:

    %Vor%

    Implementierung:

    %Vor%
  2. Verwenden Sie einen Builder. Ich habe nicht gesehen, dass dies viel in Javascript verwendet, aber dies ist einer der häufigsten Workarounds in Java, wenn ein Objekt asynchron erstellt werden muss. Natürlich wird das Builder-Muster verwendet, wenn ein Objekt erstellt wird, das viele komplizierte Parameter erfordert. Welches ist genau der Anwendungsfall für asynchrone Builder. Der Unterschied besteht darin, dass ein Async-Builder kein Objekt, sondern eine Zusage für dieses Objekt zurückgibt:

    Verwendung:

    %Vor%

    Implementierung:

    %Vor%

    Implementierung mit async / await:

    %Vor%
  

Hinweis: Obwohl wir in den obigen Beispielen Versprechungen für den asynchronen Builder verwenden, sind sie nicht unbedingt notwendig. Sie können genauso einfach einen Builder schreiben, der einen Callback akzeptiert.

    
slebetman 16.04.2017, 04:41
quelle
3

Aufgrund Ihrer Kommentare sollten Sie wahrscheinlich das tun, was jedes andere HTMLElement beim Laden von Assets tut: Lassen Sie den Konstruktor eine Sideloading-Aktion starten, die je nach Ergebnis ein Lade- oder Fehlerereignis generiert.

Ja, das bedeutet, Versprechen zu nutzen, aber es bedeutet auch "Dinge genauso zu machen wie jedes andere HTML-Element", also sind Sie in guter Gesellschaft. Zum Beispiel:

%Vor%

Dies startet eine asynchrone Last des Quell-Assets, die, wenn sie erfolgreich ist, in onload endet und wenn sie schief geht, in onerror endet. Also, mach deine eigene Klasse das auch:

%Vor%

Und dann machen Sie die renderLoaded / renderError-Funktionen mit den Ereignisaufrufen und dem Schatten-Dom:

%Vor%

Beachten Sie auch, dass ich Ihre id in eine class geändert habe, denn wenn Sie nicht irgendeinen seltsamen Code schreiben, der nur eine einzige Instanz Ihres <e-mail> -Elements auf einer Seite erlaubt, können Sie keine eindeutige ID und verwenden Ordne es dann einer Reihe von Elementen zu.

    
Mike 'Pomax' Kamermans 16.04.2017 04:57
quelle
0

Variation des Builder-Musters mit call ():

%Vor%     
Jeff Lowery 27.03.2018 23:08
quelle
-1

Bei den anderen Antworten fehlt das Offensichtliche. Rufen Sie einfach eine asynchrone Funktion von Ihrem Konstruktor auf:

%Vor%     
Navigateur 05.12.2017 04:13
quelle
-3

Sie sollten then function zur Instanz hinzufügen. Promise erkennt es als automatisches Objekt mit Promise.resolve automatisch

%Vor%     
吴浩锋 04.12.2017 10:45
quelle

Tags und Links