【问题标题】:How to make 2 FutureBuilders wait on the same Future in Flutter?如何让 2 个 FutureBuilders 在 Flutter 中等待同一个 Future?
【发布时间】:2020-12-30 12:15:23
【问题描述】:

我有一个Future,完成后会将一些数据添加到ChangeNotifierProvider。然后我使用 ChangeNotifierProvider 中的数据填充一些ListViews。问题是,我有 2 个屏幕,它们都从同一个 Future 获取他们需要的数据。每个屏幕都有一个返回 ListView 的 FutureBuilder。 如何让 2 个 FutureBuilders 等待“相同”的未来,而不是调用 2 次? FutureProvider 是一个解决方案吗?

【问题讨论】:

  • 要合并两个 Future 吗?
  • Like 2 API调用合二为一
  • 我有2个屏幕,每个屏幕都有一个FutureBuilder作为主体。问题是 2 个 FutureBuilder 具有相同的 Future,比如说 fetchData()。我的问题是如何避免调用 fetchData() 2 次,我只想调用一次,我希望 2 个 FutureBuilders 以相同的方式运行,等待单个调用完成。
  • 您应该可以让任意数量的FutureBuilders 在同一个Future 上等待,只要您有对Future 的引用(例如,通过存储在变量中)。
  • 你不叫未来。您评论中的myFuture 可能是一种返回未来的方法。因此,您应该只调用一次以仅创建一个 Future 并在两个 FutureBuilders 中使用该值。使用提供者将是一种创建一次值并将其提供给其他几个小部件的好方法。 Provider(create: () => createFuture()) 提供未来,是在未来的提供者中还是 FutureProvider(create: () => createFuture()) 提供未来的价值完成到(我认为它将提供 null 直到 Future 完成)

标签: flutter dart flutter-futurebuilder


【解决方案1】:

您应该使用Future.wait API,它的作用是等待所有期货完成并返回其结果或错误。

看这个例子:

  Future<String> getData() async {
    final future1 = Future<String>.delayed(Duration(seconds: 1), () => "I am");
    final future2 = Future<int>.delayed(Duration(seconds: 2), () => 100);
    final future3 = Future<String>.delayed(Duration(seconds: 3), () => "Years old!");
    final results = await Future.wait([future1, future2, future3]);

    // Doing a simple cast considering my Future will never fails in this example, you should check for exceptions/errors!
    final future1ResultOrError = results.first as String;
    final future2ResultOrError = results[1] as int;
    final future3ResultOrError = results[2] as String;
    return "$future1ResultOrError $future2ResultOrError $future3ResultOrError";
  }

您可以像使用单个 Future 一样使用它:

            FutureBuilder(
              future: getData(),
              initialData: null,
              builder: (context, shot) {
                return Text(shot.hasData ? shot.data : "Waiting for data...");
              },
            ),

这将打印:“我已经 100 岁了!”。注意它是如何从不同的 Futures 加载数据的!

编辑:

您可能希望拥有一个 Future 并将其提供给两个 FutureBuilder。见下面代码:

class _MyState extends State<MyPage> {

  Future mySingleFuture;

  Future<String> getData() async {
    final future1 = Future<String>.delayed(Duration(seconds: 1), () => "I am");
    final future2 = Future<int>.delayed(Duration(seconds: 2), () => 100);
    final future3 = Future<String>.delayed(Duration(seconds: 3), () => "Years old!");
    final results = await Future.wait([future1, future2, future3]);

    // Doing a simple cast considering my Future will never fails in this example, you should check for exceptions/errors!
    final future1ResultOrError = results.first as String;
    final future2ResultOrError = results[1] as int;
    final future3ResultOrError = results[2] as String;
    return "$future1ResultOrError $future2ResultOrError $future3ResultOrError";
  }

  @override
  void initState() {
    super.initState();
    mySingleFuture = getData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            FutureBuilder(
              future: getData(),
              initialData: null,
              builder: (context, shot) {
                return Text(shot.hasData ? shot.data : "Waiting for data...");
              },
            ),
            FutureBuilder(
              future: getData(),
              initialData: null,
              builder: (context, shot) {
                return Text(shot.hasData ? shot.data : "Waiting for data 2...");
              },
            ),
          ],
        ),
      ),
    );
  }
}

【讨论】:

  • 我理解这种情况,但我的问题恰恰相反。我有 2 个屏幕,每个屏幕都有一个 FutureBuilder 作为主体。问题是 2 个 FutureBuilder 具有相同的 Future,比如说 fetchData()。我的问题是如何避免调用 fetchData() 2 次,我只想调用一次,我希望 2 个 FutureBuilders 以相同的方式运行,等待单个调用完成。
猜你喜欢
  • 2020-09-29
  • 2013-04-21
  • 2021-02-09
  • 2017-08-03
  • 2018-09-18
  • 1970-01-01
  • 2020-08-04
  • 2019-01-25
  • 1970-01-01
相关资源
最近更新 更多