2016-06-24 13 views
2

Kann ich einige Iterable mit Async-Mapping-Funktion zuordnen? Vielleicht ist es ein Fehler, dass dieser Code sofort eine Liste von _Future ausdruckt, nicht nach 1 oder 5 Sekunden?Asynchrone iterierbare Abbildung in Dart

import 'dart:async'; 

Future<int> foo(int i) { 
    var c = new Completer(); 
    new Timer(new Duration(seconds: 1),() => c.complete(i)); 
    return c.future; 
} 

main() { 
    var list = [1,2,3,4,5]; 
    var mappedList = list.map((i) async => await foo(i)); 
    print(mappedList); 
} 

Antwort

1

Der Ausdruck (i) async => await foo(i) gibt immer noch eine Zukunft zurück. Sie können Future.wait(mappedList) verwenden, um zu warten, bis alle erstellten Futures abgeschlossen sind.

1

Hinzufügen bestimmter Typ wird erklären, was los ist:

main() async { 
    var list = [1,2,3,4,5]; 
    Iterable<Future<int>> mappedList = list.map((i) async => await foo(i)); 
    print(mappedList); // you print an Iterable of Future 

    // to get the list of int you have to do the following 
    Future<List<int>> futureList = Future.wait(mappedList); 
    List<int> result = await futureList; 
    print(result); 
} 
2

Ihr Missverständnis ist, dass Asynchron-Funktionen ein Future zurückgeben, keinen Wert. await konvertiert Async nicht in Sync.

var mappedList = list.map(
    (i) async => await foo(i) // Returns a Future, not an int 
); 

Sie drucken sind die Futures, die von (i) async => await foo(i) zurückgegeben werden.

Diese Futures sind abgeschlossen, wenn die Kette der Futures in ihnen abgeschlossen ist. Wenn der Timer ausgelöst wird: foo() wird abgeschlossen, dann await foo(i), dann Ihre Zuordnungsfunktion.

Vergleichen mit:

main() async { 
    List<int> list = [1,2,3,4,5]; 
    Iterable<Future<int>> mapped; 

    // Prints ints 1 second apart 
    mapped = list.map((i) => foo(i)); 
    for(Future<int> f in mapped) { 
    print(await f); 
    } 

    // Prints ints all at once, after 1 second wait 
    mapped = list.map((i) => foo(i)); 
    for(Future<int> f in mapped) { 
    f.then(print); 
    } 
} 

Auf Dartpad: https://dartpad.dartlang.org/151949be67c0cdc0c54742113c98b291

einige Dinge zu beachten:

List.map() gibt ein faul Iterable (kein List), was bedeutet, die Abbildungsfunktion isn‘ t aufgerufen, bis die Iterable durchlaufen wird.

Die erste Schleife wartet jeden Future vor dem Druckvorgang zu vervollständigen und im Iterable zum nächsten Punkt weitergehen, die Abbildungsfunktion für das nächste Element (und folglich foo()) wird nach genannt jedem Wert Druck, so Werte sind gedruckt in 1-Sekunden-Intervallen.

Die zweite Schleife iteriert sofort durch Iterable und richtet eine Druckfunktion ein, die ausgeführt wird, nachdem jede Future abgeschlossen ist. 5 Instanzen der Funktion foo() werden sofort aufgerufen, die alle ca. 1 Sekunde später zurückkommen, dann werden alle 5 Werte gedruckt.