Дождитесь завершения всех асинхронных функций перед выполнением во Flutter

Я использую Flutter для своего приложения. Мне нужно запросить большое количество информации из базы данных Firebase Realtime (например, 50 различных местоположений данных), поэтому мне нужно запустить их асинхронно и подождать, пока все они вернутся, прежде чем обновлять пользовательский интерфейс, чтобы показать пользователю информацию.

Как я могу добиться этого во Flutter? Используя async, await, я мог дождаться только 1 асинхронной функции.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
9 186
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пожалуйста, ознакомьтесь с методом Future.wait. С помощью Future.wait() вы можете запустить несколько запросов, а затем дождаться их завершения. Я также привел пример кода ниже.

метод ожидания

Future<List<T>> wait <T>(

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

)

Ожидает завершения нескольких фьючерсов и собирает их результаты.

Возвращает будущее, которое завершится, как только все предоставленные фьючерсы завершились либо со своими результатами, либо с ошибкой, если какой-либо из предоставленные фьючерсы терпят неудачу.

Значение возвращаемого будущего будет списком всех значений, которые были созданы в том порядке, в котором фьючерсы предоставляются путем итерации фьючерсы.

Если какое-либо будущее завершается с ошибкой, то возвращаемое будущее завершается с этой ошибкой. Если дальнейшие фьючерсы также в комплекте с ошибки, эти ошибки отбрасываются.

Если awaitError имеет значение true, возвращаемое будущее завершается с ошибкой. сразу же при первой ошибке от одного из фьючерсов. В противном случае все фьючерсы должны завершиться до того, как будет завершено возвращенное фьючерс (все еще с первой ошибкой; остальные ошибки молча отбрасываются).

В случае ошибки, cleanUp (если есть) вызывается на любом ненулевой результат успешного фьючерса. Это позволяет Ресурсы очистки, которые в противном случае были бы потеряны (поскольку возвращенный future не предоставляет доступ к этим значениям). Функция очистки не используется, если нет ошибки.

Вызов cleanUp не должен бросать вызов. Если да, то ошибка будет неперехваченная асинхронная ошибка.

См. пример кода ниже, результат всех трех фьючерсов загружается в ListView одновременно, так как Future.wait ожидает завершения всех фьючерсов, прежде чем вернуть результат:

import 'package:flutter/material.dart';

void main(List<String> args) {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  Future<List<String>> futureWait() async {
    return Future.wait([
      Future.delayed(const Duration(seconds: 1), () => "First Future Done"),
      Future.delayed(const Duration(seconds: 2), () => "Second Future Done"),
      Future.delayed(const Duration(seconds: 3), () => "Third Future Done"),
    ]);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Flutter Demo App"),
        ),
        body: FutureBuilder<List<String>>(
          future: futureWait(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              print(snapshot.data.length);
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, index) => ListTile(
                  title: Text(snapshot.data[index]),
                ),
              );
            }
            return const Center(child: CircularProgressIndicator());
          },
        ),
      ),
    );
  }
}

Другие вопросы по теме