如何将 Future<int> 转换为 int?

Posted

技术标签:

【中文标题】如何将 Future<int> 转换为 int?【英文标题】:How to convert Future<int> to int? 【发布时间】:2020-07-17 05:38:12 【问题描述】:

所以我尝试使用 fl_chart 插件显示饼图。正在从 firestore 检索图表的数据。我有这个用于显示数据的函数:

List<PieChartSectionData> showSection(AsyncSnapshot<QuerySnapshot> snapshot) 
    return List.generate(length, (i) 
      final isTouched = i == touchedIndex;
      final double fontSize = isTouched ? 25 : 16;
      final double radius = isTouched ? 60 : 50;
      return PieChartSectionData(
        color: Color(int.parse(cerealData[i].colorVal)),
        value: cerealData[i].rating,
        title: cerealData[i].rating.toString(),
        radius: radius,
        titleStyle: TextStyle(
            fontSize: fontSize,
            fontWeight: FontWeight.bold,
            color: const Color(0xffffffff)),
      );
    );
  

List.generate() 将 int 作为参数。由于我正在显示实时数据,因此我正在尝试获取我的集合中存在的文档数量。为此,我有一个名为 getLength() 的函数:

  void getLength(AsyncSnapshot<QuerySnapshot> snapshot) async 
    length = await Firestore.instance.collection('cereal').snapshots().length;
    cerealData =
        snapshot.data.documents.map((e) => Cereal.fromJson(e.data)).toList();
  

但是,当我运行代码时,我得到:

 Another exception was thrown: type 'Future<int>' is not a subtype of type 'int'

整个代码:

class _FlChartPageState extends State<FlChartPage> 
  int touchedIndex;
  var length;
  List<Cereal> cerealData;

  void getLength(AsyncSnapshot<QuerySnapshot> snapshot) async 
    length = await Firestore.instance.collection('cereal').snapshots().length;
    cerealData =
        snapshot.data.documents.map((e) => Cereal.fromJson(e.data)).toList();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: StreamBuilder<QuerySnapshot>(
          stream: Firestore.instance.collection('cereal').snapshots(),
          builder: (context, snapshot) 
            getLength(snapshot);
            if (!snapshot.hasData)
              return CircularProgressIndicator();
            else 
              return PieChart(PieChartData(
                  pieTouchData: PieTouchData(touchCallback: (pieTouchResponse) 
                    setState(() 
                      if (pieTouchResponse.touchInput is FlLongPressEnd ||
                          pieTouchResponse.touchInput is FlPanEnd) 
                        touchedIndex = -1;
                       else 
                        touchedIndex = pieTouchResponse.touchedSectionIndex;
                      
                    );
                  ),
                  borderData: FlBorderData(show: false),
                  sectionsSpace: 0,
                  centerSpaceRadius: 40,
                  sections: showSection(snapshot)));
            
          ),
    );
  

  List<PieChartSectionData> showSection(AsyncSnapshot<QuerySnapshot> snapshot) 
    return List.generate(length, (i) 
      final isTouched = i == touchedIndex;
      final double fontSize = isTouched ? 25 : 16;
      final double radius = isTouched ? 60 : 50;
      return PieChartSectionData(
        color: Color(int.parse(cerealData[i].colorVal)),
        value: cerealData[i].rating,
        title: cerealData[i].rating.toString(),
        radius: radius,
        titleStyle: TextStyle(
            fontSize: fontSize,
            fontWeight: FontWeight.bold,
            color: const Color(0xffffffff)),
      );
    );
  


我在某处读到,等待未来摆脱了未来。但这在这里行不通。 我该如何解决?

编辑:如果我只是在 List.generate() 中传递文档数量而不是长度,它就可以工作。但是,如果集合发生更改,这将不起作用。那么如何将 Future 转换为 int 呢?

【问题讨论】:

我确定错误来自 showSection() 中的 List.generate()。由于 generate() 需要一个 int,并且它得到 Future,因此会引发异常。 是的,但这不起作用 【参考方案1】:

我认为你没有得到文件的长度,如果你想得到文件的长度,你得到的是快照的长度:

QuerySnapshot querySnapshot = await Firestore.instance.collection('cereal').getDocuments();
    int length = querySnapshot.documents.length;

【讨论】:

对不起,但这并不能解决我的问题。首先,我不会通过快照来获取长度。我正在传递快照,所以我可以获得一个对象列表来填充谷物数据数组。其次,我不能在非异步函数中使用 await。你的方法我还是试过了,还是不行。 好的,这解决了我的问题。谢谢。但我没有得到一件事 - 我认为快照和文档是相同的。 snapshots() 返回什么? 快照包含文档列表以及元数据信息,请查看firebase.google.com/docs/reference/js/…【参考方案2】:

在 get getLength 函数中,您尝试获取长度,这实际上是返回未来的异步任务,因此您会遇到以下错误。

用以下方法改变你的方法

getLength()async
 Firestore.instance.collection('cereal').snapshots().length.then((len)
  length = len;
  cerealData =
        snapshot.data.documents.map((e) => Cereal.fromJson(e.data)).toList(); 
  );

【讨论】:

以上是关于如何将 Future<int> 转换为 int?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 std::future<T> 转换为 std::future<void>?

如何将 Future<dynamic> 转换为 dart:flutter 中的字符串

将 Future<List> 从 Firestore 转换为 List<String> - Flutter Firebase [重复]

如何将 Future<int> 传递给超类

使用flutter_local_notifications时如何在Flutter中将Future<Null>转换为Future<dynamic>?

如何在 Flutter/Dart 中将 Future<double> 转换为 double?