Dart Future.wait для нескольких фьючерсов и получения результатов разных типов - PullRequest
0 голосов
/ 08 апреля 2020

Я использую Flutter для загрузки 3 разных наборов данных с сервера, а затем что-то делаю со всеми 3 наборами. Я мог бы сделать это:

List<Foo> foos = await downloader.getFoos();
List<Bar> bars = await downloader.getBars();
List<FooBars> foobars = await downloader.getFooBars();

processData(foos, bars, foobars);

Но я бы предпочел загружать все 3 набора данных асинхронно параллельно . Я видел, что у Дарт есть этот метод Future.wait :

Future<List<T>> wait <T>(
   Iterable<Future<T>> futures, {
   bool eagerError: false, 
   void cleanUp(
      T successValue
   )
}) 

Однако похоже, что он будет возвращать только значения того же типа (T). У меня есть 3 разных типа, так что я не понимаю, как я могу использовать это и вернуть свои 3 набора данных.

Какой лучший альтернативный способ добиться этого?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 08 апреля 2020

Ну, тип T - это обобщенный c тип

Вы знаете свои типы, так что вы можете работать с ними.

Если вы используете FutureBuilder, вы можете получить доступ разные результаты, используя это. (в том же порядке, в котором вы их вводите методом Future.wait)

snapshot.data[0] // maybe type List<Foo>
snapshot.data[1] // maybe type List<Bar>
snapshot.data[2] // maybe type String
0 голосов
/ 08 апреля 2020

Вам необходимо адаптировать каждый из ваших Future<T> s к общему типу Future. Вы можете использовать Future<void>:

List<Foo> foos;
List<Bar> bars;
List<FooBars> foobars;

await Future.wait<void>([
  downloader.getFoos().then((result) => foos = result),
  downloader.getBars().then((result) => bars = result),
  downloader.getFooBars().then((result) => foobars = result),
]);

processData(foos, bars, foobars);

. Или, если вы предпочитаете от await до .then(), вызов Future.wait может быть:

await Future.wait<void>([
  (() async => foos = await downloader.getFoos())(),
  (() async => bars = await downloader.getBars())(),
  (() async => foobars = await downloader.getFooBars())(),
]);
0 голосов
/ 08 апреля 2020

Я думаю, что это невозможно сделать супер хорошим способом. Все, что вы можете сделать, это что-то вроде этого:

void main() async {
  List<List<dynamic>> result = await Future.wait<List<dynamic>>([
    getStringData(),
    getIntData(),
  ]);

  print(result[0]);
  print(result[1]);
}

Future<List<String>> getStringData() {
  return Future.value(["a", "b"]);
}

Future<List<int>> getIntData() {
  return Future.value([1, 2]);
}
...