在体内重用Future调用的建议方法/最佳做法是什么? [英] What is the recommended approach / best practice to reuse a Future call in body?

查看:84
本文介绍了在体内重用Future调用的建议方法/最佳做法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是个新手,遇到了一种情况,我需要重用异步调用中的数据,在进行了一些研究之后,我发现了很好的FutureBuilder Widget,并且我正在使用它,效果很好,但是我遇到了这种情况我需要在两个不同的小部件中使用来自将来调用的数据,例如下面的代码片段,该代码片段会导致异步调用执行两次,因此我想避免这种情况.

I am new to flutter and I got a situation where I need to reuse data from an asynchronous call, after researching a bit I found out about the nice FutureBuilder Widget and I am using, it works great but I have this situation where I need the data from the future call in two different widgets like the code fragment below which causes the async call to be executed twice and I would like to avoid it.

如何避免两次通话?在这种情况下,推荐的方法是什么?我找不到这种情况的参考/推荐.

How to avoid the two calls? What's the recommended approach in this case? I couldn't find a reference/recommendation for this situation.

body: Column(
        children: [

          Container(
            height: 200,
            child: FutureBuilder(
              future: weight.findAll(),
              builder: (context, snapshot) {
                  if(!snapshot.hasData) {
                    return Center(child: CircularProgressIndicator());
                  } else {
                    this._seriesList = _plotWeightSeries(snapshot.data);
                    return _lineChart();
                  }
              },
            ),

          ),

          Expanded(
            child: FutureBuilder(
              future: weight.findAll(),
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return Center(child: CircularProgressIndicator());
                } else {
                  return _getSlidableListView(snapshot.data);
                }
              },
            ),
          ),
        ],
      ),

推荐答案

以下是使用 Flutter挂钩 Riverpod .

我定义一个FutureProvider从服务器获取权重:

I define a FutureProvider to fetch the weights from the server:

final weightsProvider = FutureProvider((ref) => findAllWeights());

Future<List<double>> findAllWeights() async {
  print('FETCHING DATA'); // This gets run only once
  final random = Random();
  await Future.delayed(Duration(seconds: 2));
  return List.generate(20, (index) => 50 + 20 * random.nextDouble());
}

然后,我在 WidgetOne 中使用结果来计算SUM,并在 WidgetTwo 中使用结果来计算AVERAGE.如您所见, FETCHING DATA 仅发生一次.

And then, I use the result in both my WidgetOne to calculate the SUM and my WidgetTwo to calculate the AVERAGE. As you will see, the FETCHING DATA only happens once.

import 'dart:math' show Random;

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/all.dart';

void main() {
  runApp(
    ProviderScope(
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
        home: HomePage(),
      ),
    ),
  );
}

final weightsProvider = FutureProvider((ref) => findAllWeights());

Future<List<double>> findAllWeights() async {
  print('FETCHING DATA'); // This gets run only once
  final random = Random();
  await Future.delayed(Duration(seconds: 2));
  return List.generate(20, (index) => 50 + 20 * random.nextDouble());
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          WidgetOne(),
          WidgetTwo(),
        ],
      ),
    );
  }
}

class WidgetOne extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final weights = useProvider(weightsProvider);
    return Card(
      child: Column(
        children: [
          Text('SUM of the weights'),
          weights.when(
            data: (data) => Text(data.reduce((a, b) => a + b).toString()),
            loading: () => CircularProgressIndicator(),
            error: (_, __) => Text('Something bad happended'),
          ),
        ],
      ),
    );
  }
}

class WidgetTwo extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final weights = useProvider(weightsProvider);
    return Card(
      child: Column(
        children: [
          Text('AVERAGE of the weights'),
          weights.when(
            data: (data) =>
                Text((data.reduce((a, b) => a + b) / data.length).toString()),
            loading: () => CircularProgressIndicator(),
            error: (_, __) => Text('Something bad happended'),
          ),
        ],
      ),
    );
  }
}

在此示例中,我使用了Riverpod,但还有其他状态管理,请在此处查看精选的状态管理方法列表.

I used Riverpod in this examples but there are other State Management, check here for a curated List of state management approaches.

这篇关于在体内重用Future调用的建议方法/最佳做法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆