Ich versuche (noch eine andere) Sprache zu erstellen, die zu JavaScript kompiliert wird. Eine der Funktionen, die ich haben möchte, ist die Möglichkeit, die asynchronen Operationen von JavaScript synchron auszuführen (nicht genau synchron - natürlich ohne den Hauptthread zu blockieren). Weniger reden, mehr Beispiele:
/* These two snippets should do exactly the same thing */
// the js way
var url = 'file.txt';
fetch(url)
.then(function (data) {
data = "(" + data + ")";
return sendToServer(data);
}).then(function (response) {
console.log(response);
});
// synchronous-like way
var url = 'file.txt';
var response = sendToServer("(" + fetch(url) + ")");
console.log(response);
Was ist die eleganteste Art, es wieder in JS zu kompilieren?
Die Kriterien, sortiert nach Wichtigkeit:
- Performance
- Abwärtskompatibilität
- Lesbarkeit des kompilierten Codes (nicht wirklich wichtig)
Es gibt verschiedene Möglichkeiten, dies umzusetzen. Diese drei kamen mir in den Sinn:
Versprechen verwenden:
f(); a( b() );
würde sich in verwandelnf().then(function(){ return b() }).then(function(x){ a(x) });
- Profis: relativ einfach zu implementieren, polyfillable zurück zu ES3
- Nachteile: Erstellen einer neuen Funktion und einer Proxy-Instanz für jeden Funktionsaufruf
-
f(); a( b() );
würde sich in verwandelnyield f(); tmp = yield b(); yield a( tmp );
- Profis: schöneres Javascript
- Nachteile: Erstellen von Proxys, Generatoren und Iteratoren bei jedem Schritt, auch nicht polyfüllbar
- BEARBEITEN: Tatsächlich können sie mit einem anderen Recompiler (z. B. Regenerator ) mehrfach gefüllt werden.
Verwenden von synchronem XMLHttpRequest:
- Fordern Sie ein Serverskript an, das auf einen weiteren Aufruf von einer anderen Stelle im Code wartet
- Profis: de facto keine Änderungen im Code, super einfach zu implementieren
- Nachteile: erfordert Serverskript (=> keine Portabilität, nur Browser); Darüber hinaus blockiert synchrones XMLHttpRequest den Thread, sodass er überhaupt nicht funktioniert
- EDIT: Es würde tatsächlich in einem Worker funktionieren
Das Hauptproblem ist, dass man bis zur Laufzeit nicht erkennen kann, ob eine Funktion asynchron ist . Dies führt dazu, dass die beiden Lösungen, die zumindest funktionieren , viel langsamer sind als reines JS. Deshalb frage ich:
Gibt es bessere Möglichkeiten zur Implementierung?
Aus Antworten:
Schlüsselwort abwarten (@ MI3Guy)
- C # Weg (was gut ist !)
- führt ein neues Schlüsselwort ein (das als Funktion getarnt werden kann (Bürger erster Klasse), das z. B. ausgelöst wird, wenn der Programmierer versucht, es als Argument zu übergeben).
- Woher wissen Sie, dass diese Funktion asynchron ist? Keine anderen Schlüsselwörter!
- Jede Funktion, die ein
await
Schlüsselwort enthält, wird asynchron? - Wenn der Code erreicht ist
await
, gibt er ein Versprechen zurück? Sonst behandelt als eine gewöhnliche Funktion?
- Jede Funktion, die ein
f(); a( b() );
würde sich in f().then(b).then(a);
Sie nicht Funktionen einschließen.
synchronously (without blocking the thread, of course)
Du benutzt dieses Wort weiter. Ich denke nicht, dass es bedeutet, was Sie denken, dass es bedeutet, weil synchron "Blockieren des Threads" bedeutet.