2016-03-23 5 views
1

Ich weiß sicher, mein Gehirn ist nicht ganz klar auf Async/erwarten, also brauche ich etwas Klarheit. Ich sehe eine Menge Beispiele, in denen in einigen Zeilen auf wait gewartet wird und nicht auf anderen in einer async-markierten Funktion. Zum Beispiel habe ich nur selten, wenn ein Beispiel so gesehen (ich die print-Anweisung als Beispiel für etwas Einfaches/basic verwende.):Wenn ich möchte, dass alles innerhalb einer Funktion ausgeführt wird, erwarte ich jede Zeile?

myFunction() async { 
    await functionA(); 
    await print("This really long thing that's going to print out."); 
    await functionB(); 
    await MyExtraClass.lookupSomethingQuickly(); 
    ... 
} 

So die Beispiele, die ich sehen, dass es in der Regel etwas wie folgt aus:

myFunction() async { 
    await functionA(); 
    print("This really long thing that's going to print out."); 
    await functionB(); 
    MyExtraClass.lookupSomethingQuickly(); 
    ... 
} 

Also ich frage mich, ob es nur eine Vermutung, dass einfache Dinge in Ordnung oder theoretisch beenden, wenn await vor jeder Zeile setzen wird, was soll ich in Fällen tun, wo ich absolut Linie 1 brauchen Linie zu folgen 2, um Zeile 3 usw. zu folgen ... Wie wäre es, wenn ich unbedingt den Druck beenden müsste, bevor die FunktionB() ausgeht?

Im Wesentlichen stelle ich fest, dass ich jedes Mal, wenn ich eine Funktion mit async/awaite schreibe, einen Urteilsspruch in jeder Zeile schreibe, und ich weiß nie, ob mein Code aufgrund von gutem Timing und Glück funktioniert oder ob es Fälle geben würde Wirf die Ausführung ab.

Antwort

5

async/await ist asynchron Code einfacher zu schreiben, zu lesen und zu begründen. Der Synchronous-Code benötigt keine solche Unterstützung.
Für Asynchron-Programmierung in Dart auch https://www.dartlang.org/docs/tutorials/futures/

sehen Wenn Sie dieses Codebeispiel

nehmen
import 'dart:async' show Future; 
void main() { 
    doSomethingAsync().then((_) => print('afterwards')); 
    print('at last'); 
} 

Future doSomethingAsync() { 
    return new Future.delayed(const Duration(seconds: 1),() { 
    print('done something'); 
    }); 
} 

es in DartPad

Versuchen Sie, die

zuletzt

etwas getan druckt danach

Wenn Sie mit Asynchron-Ausführung nicht vertraut sind dies könnte überraschend sein

Dies liegt daran, den Code zu Future.delayed() bestand mit einer Verzögerung von 1 Sekunde ausgeführt wird. Die Future -Instanz, die von doSomethingAsync() zurückgegeben wird, ist "abgeschlossen", wenn der Code in Future.delayed() ausgeführt wurde.

In dieser Linie

doSomethingAsync().then((_) => print('afterwards')); 

wir nennen .then(...) auf die zurück Future durch doSomethingAsync() und einen Verschluss (Inline-Funktion) zu .then(...) passieren. ((_) => print('afterwards')).

Ein Merkmal Future ist, dass es den Code übergeben then(...) ruft, nachdem er abgeschlossen wurde (in unserem Fall, wenn nach 1 sec done something Verzögerung gedruckt wurde).

So geht die Ausführung so etwas wie

  • Anruf doSomethingAsync() der Zeitplan einen Aufruf an print('done something) für die spätere Ausführung und einen Future
  • Aufruf gibt print('at last'); die gerade at last
  • nach 1 Sekunde Verzögerung druckt print('done something') genannt wird
  • Die Future zurückgegeben von doSomethingAsync() ist abgeschlossen
  • die Future Anrufe `(_) => drucken ('nachher')
  • main() endet.

Wenn wir verwenden async/await der Code sieht aus wie

import 'dart:async' show Future; 
Future main() async { 
    await doSomethingAsync(); 
    print('afterwards'); 
    print('at last'); 
} 

Future doSomethingAsync() { 
    return new Future.delayed(const Duration(seconds: 1),() { 
    print('done something'); 
    }); 
} 

Probieren Sie es in DartPad

Wenn Lauf, der Ausgang ist

etwas getan
danach
zu guter Letzt

wir auch async/await in doSomethingAsync() verwenden könnte, aber jetzt konzentrieren wir uns nur auf main()

Nun ist die Ausführung sieht aus wie

  • Anruf doSomething() und warten auf die zurück Future abzuschließen
  • print('done something') wird ausgeführt und Future wird vervollständigt
  • die Ausführung von Code nach await weiter
  • print('afterwards');
  • print('at last');

Dies ist wahrscheinlich das Verhalten erwartet.

Zu Ihrer ursprünglichen Frage. await ist nur erforderlich, wenn ein Anruf eine Future zurückgibt und der folgende Code nur ausgeführt werden soll, wenn die Future abgeschlossen ist. Wenn der Anruf keine Future zurückgibt, gibt es nichts zu warten.

await print('xxx') ist immer noch gültigen Code. Dies ist zur Unterstützung von Funktionen, die manchmal einige asynchrone Arbeit und geben Sie eine Future zurück, aber manchmal haben die asynchrone Arbeit nicht zu tun und den Code sofort ausführen und nur danach zurückkehren. In diesem Fall gibt es nichts zu warten.

someTimesAsync() { 
    if(new DateTime.now().weekday == 1) { 
    return new Future.delayed(const Duration(seconds: 1),() { 
     print('done something'); 
    }); 
    } else { 
    print('done something'); 
    } 
} 
await someTimesAsync(); 

Arbeiten in beiden Fällen. Wenn es nicht wäre, wäre das umständlich.

Für weitere Informationen über async/await siehe auch https://www.dartlang.org/articles/await-async/

+0

Wie immer schätze ich Ihre Antwort richtig. Dies hat mir geholfen, ein bisschen besser zu verstehen und ist wahrscheinlich die beste Erklärung, die ich bisher gelesen habe. Ich wollte weitermachen, als du sagtest "Wenn der Anruf keine Zukunft zurück gibt, dann gibt es nichts, worauf du warten musst." Ich denke, ich habe Probleme damit, wenn ich meine eigenen Funktionen in anderen Funktionen verwende. Sollte ich eine Zukunft zurückgeben, wenn eine meiner Funktionen einige Zeit dauern könnte (z. B. 1000 Tennisspieler zu zählen)? Wenn ich kein Future zurückgebe, wird der Code, der diese Funktion verwendet, automatisch warten? – Dan

+0

Nicht sicher, ob das eine Frage ist. Ich würde es so erklären. Wenn du jemandem sagst, dass er eine Aufgabe erledigen soll und dich kontaktieren soll, wenn er fertig ist und du damit beschäftigt bist zu warten, bis er zu dir zurückkommt, dann ist das was "erwarten". Wenn du zu jemandem sprichst, erreiche dieses Ding und er gibt dir das Ding sofort, dann gibt es kein Warten mehr, da du nicht einmal die Möglichkeit hast, etwas dazwischen zu tun. Dann brauchen Sie nicht "warten", weil die Aktion in "einem Schritt" abgeschlossen wurde. –

+0

Das hilft und ich fühle mich dem Verstehen näher. Ich glaube, ich stecke fest auf dem, was sofort ist. Also, was ist mit diesem Szenario: Angenommen, ich habe eine Funktion, die eine Million Zufallszahlen zusammenfasst - ein einfacher Lauf wie total + = r und es gibt total zurück. Und dann habe ich eine andere Funktion, die die Summe von nur 3 Zufallszahlen wie return r1 + r2 + r3 zurückgibt. Für beide Fälle brauche ich unbedingt die Summe, bevor ich fortfahre. In meinem Gehirn denke ich "Ich muss auf die erste Funktion warten, weil es länger dauern kann, aber vielleicht nicht auf der zweiten, weil es schnell ist." Kannst du mir sagen, wie falsch ich denke? – Dan