Wie eine asynchrone Dart-Aufruf synchron?
Ich bin auf dem Weg zu bewerten Dart für eine Deutsche Firma, die von der Portierung diverser Java-Programme zu Dart und zu vergleichen und die Ergebnisse analysieren. Im browser Dart gewinnt Hände nach unten. Für die server-software die Leistung schien ein ernstes isssue (siehe diese Frage von mir) aber das hat meist entschärft.
Nun bin ich im Bereich der Portierung von einigen "einfachen" Befehl-Linie Werkzeuge, bei denen ich nicht erwarten, dass alle ernsthaften Probleme, aber es gibt wenigstens eins. Einige der tools, tun, machen, HTTP-Anfragen zu sammeln, die Daten und den stand-alone-Dart virtual machine unterstützt nur diese in einem asynchronen Mode. Suche durch alle die ich finden konnte, scheint es nicht möglich zu sein, verwenden Sie alle asynchronen Aufruf in eine meist synchrone software.
Verstehe ich, ich könnte die Umstrukturierung der verfügbaren synchronen software in einem asynchronen ein. Aber diese machen würde ein gut gestaltetes Stück software in etwas weniger lesbar und schwerer zu Debuggen und zu warten. Für einige software-Stücke, die diese macht einfach keinen Sinn.
Meine Frage: gibt es eine (übersehen von mir) Möglichkeit zum einbetten von einer asynchronen Aufruf in eine synchron aufgerufene Methode?
Ich kann mir vorstellen, dass es nicht zu schwierig, ein system-call, nutzbar nur innerhalb des Haupt-Threads, die nur überträgt den Vollzug an die ganze Liste der in der Warteschlange asynchrone Funktionsaufrufe (die zimmerreserviereung, ohne das Ende der Haupt-thread der ersten), und sobald der Letzte hat ausgeführt, gibt und weiterhin den Haupt-thread.
Etwas, das könnte wie folgt Aussehen:
var synchFunction() {
var result;
asyncFunction().then(() { result = ...; });
resync(); //the system call to move to and wait out all async execution
return result;
}
Dass eine solche Methode vereinfacht würde die lib-APIs als auch. Die meisten "sync" nennt, könnte entfernt werden, weil die re-synchronisation aufrufen, würde die Arbeit machen. Es scheint wie eine logische Idee, ich finde es immer noch irgendwie existiert, und ich es verpasst haben. Oder gibt es einen ernsthaften Grund, warum das nicht funktionieren würde?
Nach denken über die empfangene Antwort aus lm
(siehe unten) für die zwei Tage, die ich immer noch nicht verstehen, warum die Kapselung eines asynchronen Dart-call-in eine synchrone man sollte nicht möglich sein. Es ist getan in die "normale" synchrone Programmierung Welt die ganze Zeit. In der Regel können Sie warten, bis eine erneute Synchronisierung durchführen, indem Sie entweder immer ein "Fertig" von der asynchrone routine oder wenn etwas nicht weiter nach einem timeout.
In diesem Sinne mein Erster Vorschlag könnte verbessert werden, wie:
var synchFunction() {
var result;
asyncFunction()
.then(() { result = ...; })
.whenComplete(() { continueResync() }); //the "Done" message
resync(timeout); //waiting with a timeout as maximum limit
//Either we arrive here with the [result] filled in or a with a [TimeoutException].
return result;
}
Den resync()
macht das gleiche, das normalerweise geschehen würde, nachdem er die main
Methode ein Isolat ist, beginnt es die Ausführung der in der Warteschlange von asynchronen Funktionen (oder wartet auf Ereignisse, um Sie ausführbar). Sobald es auf eine continueResync()
Aufruf ein flag gesetzt, welches verhindert, dass dieses asynchrone Ausführung und resync()
kehrt zu dem Haupt-thread. Wenn keine continueResync()
nennen ist aufgetreten, während die gegebenen timeout
Zeit es zu bricht die asynchrone Ausführung und Blätter resync()
mit einem TimeoutException
.
Für einige Gruppen von software, die nutzen aus gerade synchronen Programmierung (nicht die client-software und nicht der server-software) eine solche Funktion würde lösen viele Probleme für die Programmierer, die sich mit asynchrounous-nur Bibliotheken.
Ich glaube, dass ich auch eine Lösung gefunden für das Haupt-argument in lm
's argumentation weiter unten. Deshalb meine Frage steht immer noch mit Bezug auf das "enhanced" - Lösung, die ich vorgeschlagen habe: gibt es etwas, das wirklich macht es unmöglich, zu implementieren, dass in Dart?
- Es ist nicht unmöglich, aber es würde eine wichtige re-Architektur des Dart-runtime-Philosophie, und vielleicht brauchen würde, Dart-multi-threaded. Wenn Sie es machen, Dart-multi-threaded dann Dart-Programmierer würden alle haben zu Beginn den Umgang mit thread-Synchronisation-Probleme, das würde erheblich erschweren das Leben eines jeden einzelnen sowie brechen eine Menge von vorhandenen code.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nur Zeit, Sie können Textumbrüche in einer async-Methode synchron ist, wenn Sie nicht brauchen, um einen Wert zurück.
Zum Beispiel, wenn Sie möchten, deaktivieren Sie die Schaltfläche speichern, speichern Sie die Ergebnisse an den server asynchron-und re-aktivieren Sie die Schaltfläche speichern, wenn der job getan ist, können Sie schreiben es so:
Beachten Sie, dass die
saveClicked
Methode ist voll synchron, aber führt diesave
Methode asynchron.Beachten Sie, dass wenn Sie
saveClicked
async, nicht nur Sie zu nennen mit dem async-pattern, aber der gesamte Methodenrumpf wird asynchron ausgeführt, so dass der speichern-button wird nicht mehr deaktiviert werden, wenn die Funktion zurückgibt.Für die Vollständigkeit der asynchronen version von
saveClicked
sieht wie folgt aus:Den
resync
- Funktion kann nicht umgesetzt werden in Dart ist die aktuelle Ausführung Modell.Asynchrone Ausführung ist ansteckend. Eine synchrone Funktion zurückgeben müssen, bevor andere asynchrone Ereignisse ausführen können, so gibt es keine Möglichkeit synchron zu warten, bis asynchrone Ausführung.
Ausführung in Dart ist die single-Thread-und event-basiert. Es gibt keine Möglichkeit für die
resync
Funktion zu sperren, ohne dass es auch blockieren alle anderen die Ausführung in der gleichen isolieren, so dass die ausstehenden asynchronen Operationen, die nie passieren wird.Blockieren Sie den synchronen Ausführungsmodus und fortsetzen der Ausführung etwas anderes, Sie schützen zu müssen, den gesamten call-stack bis zu diesem Zeitpunkt wieder, und wieder später, wenn die synchrone Operationen abgeschlossen wurden. Wenn Sie diese Funktionalität, dann gibt es wohl bessere Wege, Dinge zu tun, als Zukunft und Streamen 🙂
Auch, darauf warten, dass "alle asynchronen Ausführung" ist nicht gut definiert ist, in einem event-basierten system. Es könnte ein broadcast-Stream ausstrahlen Veranstaltungen kommen aus dem Netzwerk, ein periodischer timer, oder eine receive-port, um Daten von einem anderen zu isolieren, oder irgendeine andere Quelle der Ereignisse, die Sie können nicht warten, denn Sie kommen von außen isolieren oder Ereignis-Prozess. Wenn der aktuelle isolieren heruntergefahren, es könnte senden Sie eine final shut-down-Nachricht zu einem anderen zu isolieren, so effektiv die "asynchrone Ausführung" ist nicht vorbei, bis die isolieren stirbt.
Mithilfe der async/await-syntax, werden Sie nicht bekommen eine synchrone operation, aber es wird einfacher sein, um code, der ähnlich wie der asynchrone Betrieb:
Es wird nicht warten, bis asynchrone Operationen, die nicht reflektiert in der
Future
zurückgegebenasyncFunction
, aber das ist der job vonasyncFunction
zu erst beendet, wenn seine Vorgänge abgeschlossen sind.Dart ist von Natur aus async. Versuche zu vermeiden, asynchronity nicht funktionieren.
Es gibt sync-Versionen von einigen API-Aufrufe beispielsweise in
dart:io
und in einigen Situationen könnte es scheinen einfacher zu verwenden, Sie stattdessen aber, weil es nicht sync-Versionen für alle Methoden/Funktionen, die Sie nicht vermeiden können, async ganz.Mit der jüngsten Einführung der
async
/await
feature async Programmierung sehr viel einfacher und der code sieht schon fast wie ein sync-code (ist es aber nicht).Wenn ein Anruf ging async es bleibt async. Soweit ich weiß, gibt es nichts, was Sie dagegen tun können.
async
/await
verfügbar ist, sehe ich nicht, warum sollte dies ein problem sowieso. Async bedeutet, dass ein callback Hinzugefügt, um die Ereignis-queue für die spätere Ausführung. Ich kann nicht sehen, wie könnte dies sogar möglich sein, zurück zu synchronisieren die Ausführung in der aufrufenden Funktion.Ja, das ist so spät, aber ich denke, das ist ein cooles feature, neue Leute kennen sollten.
Dort ist eine Möglichkeit, aber die Dart-docs warnen gegen es (und ist es irgendwie "experimentell", aber die Auswirkungen sind nicht wirklich besprochen).
Den
waitFor
Befehl.Dass Sie im Grunde pass in eine asynchrone Funktion, die zurückgibt einen
Future
eine optionaletimeout
parameter, und diewaitFor
Funktion gibt das Ergebnis aus.Beispiel: