2016-06-24 1 views
2

Могу ли я сопоставить некоторые Iterable, используя функцию асинхронного отображения? Может быть, это ошибка, что этот код печатает список _Future сразу, а не ints через 1 или 5 секунд?Асинхронное итерируемое отображение в дроте

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); 
} 

ответ

1

Выражение (i) async => await foo(i) все еще возвращает будущее. Вы можете использовать Future.wait(mappedList), чтобы дождаться завершения всех созданных фьючерсов.

1

Добавление некоторого типа будет объяснить, что происходит:

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

Ваше недоразумение, что асинхронные функции возвращают Future, а не значение. await не конвертирует асинхронную синхронизацию.

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

Вы печатаете являются фьючерсы, возвращаемые (i) async => await foo(i).

Эти фьючерсы завершены, когда цепочка фьючерсов внутри них завершена. Когда срабатывает таймер: foo() завершает работу, затем await foo(i), затем ваша функция отображения.

Сравнить с:

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); 
    } 
} 

На Dartpad: https://dartpad.dartlang.org/151949be67c0cdc0c54742113c98b291

Некоторые вещи, чтобы отметить:

List.map() возвращает ленивым Iterable (не List), что означает функцию отображения ISN» t до тех пор, пока не будет выполнено повторение Iterable.

Первых ожиданий цикла для каждого Future, чтобы завершить перед печатью и перейти к следующему пункту в Iterable, функция отображения для следующего элемента (и, следовательно, foo()) называются после печатью каждого значения, поэтому значения с интервалом в 1 секунду.

Вторая петля итерации через Iterable немедленно, настройка функции печати для выполнения после завершения каждого Future. Вызывается сразу 5 экземпляров функции foo(), которые все возвращаются примерно на 1 секунду позже, затем выводятся все 5 значений.

Смежные вопросы