构建FutureBuilder <list <dynamic >>时引发了StackOverflowError

时间:2018-11-13 16:14:07

标签: dart flutter future

我正在使用《纽约时报》的畅销书API,以便可以获取畅销书中每个类别的书籍清单。我的代码如下:

import "dart:convert";
import "package:flutter/material.dart";
import "package:http/http.dart" as http;
import "package:best_sellers/api.dart";

class BestSellersList extends StatefulWidget {
  final API api;
  final List<dynamic> categories;

  BestSellersList({Key key, @required this.api, @required this.categories}) : super(key: key);

  @override
  _BestSellersList createState() => _BestSellersList();
}

class _BestSellersList extends State<BestSellersList> {
  String base, key;
  List<dynamic> categories;
  Future<List<dynamic>> books;

  Future<List<dynamic>> fetchBooks() async {
    try {
      final books = categories.map((category) async {
        final listNameEncoded = category["list_name_encoded"];
        final uri = "$base/$listNameEncoded?api-key=$key";
        final response = await http.get(uri);
        if (response.statusCode == 200) {
          final responseBody = json.decode(response.body);
          final books = responseBody["results"]["books"];
          return books;
        } else { throw Exception(); }
      }).toList();

      if (books.isNotEmpty) {
        return books;
      }
      throw Exception();
    } catch(e) { /**/ }
  }

  void updateBooks() {
    setState(() {
      books = updateBooks();
    });
  }

  @override
  initState() {
    super.initState();
    base = widget.api.base;
    key = widget.api.key;
    categories = widget.categories;
    print("categories.length: ${categories.length}"); // categories.length: 55
    updateBooks();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: books,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return ListView.builder(
            itemCount: snapshot.data.length,
            itemBuilder: (context, index) {
              final displayName = snapshot.data[index]["display_name"];
              return ListTile(title: Text(displayName));
            }
          );
        } else if (snapshot.hasError) {
          return Center(child: Column(
            children: [
              Text(snapshot.error.toString()),
              RaisedButton(
                onPressed: () => updateBooks(),
                child: Text("RETRY"),
              ),
            ],
          ));
        }

        return Center(child: CircularProgressIndicator());
      }
    );
  }
}

在运行我的代码时,我得到以下堆栈跟踪:

    I/flutter ( 5231): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════
I/flutter ( 5231): The following StackOverflowError was thrown building FutureBuilder<List<dynamic>>(state:
I/flutter ( 5231): _FutureBuilderState<List<dynamic>>#a3252):
I/flutter ( 5231): Stack Overflow
I/flutter ( 5231): When the exception was thrown, this was the stack:
I/flutter ( 5231): #0      State.mounted (package:flutter/src/widgets/framework.dart:969:3)
I/flutter ( 5231): #1      State.setState.<anonymous closure>
(package:flutter/src/widgets/framework.dart:1113:63)
I/flutter ( 5231): #2      State.setState (package:flutter/src/widgets/framework.dart:1123:6)
I/flutter ( 5231): #3      _BestSellersList.updateBooks (package:best_sellers/best_sellers_list.dart:44:9)
I/flutter ( 5231): #4      _BestSellersList.updateBooks.<anonymous closure>
(package:best_sellers/best_sellers_list.dart:45:19)
I/flutter ( 5231): #5      State.setState (package:flutter/src/widgets/framework.dart:1124:30)
I/flutter ( 5231): #6      _BestSellersList.updateBooks (package:best_sellers/best_sellers_list.dart:44:9)
I/flutter ( 5231): #7      _BestSellersList.updateBooks.<anonymous closure>
(package:best_sellers/best_sellers_list.dart:45:19)
I/flutter ( 5231): #8      State.setState (package:flutter/src/widgets/framework.dart:1124:30)
I/flutter ( 5231): #9      _BestSellersList.updateBooks (package:best_sellers/best_sellers_list.dart:44:9)
I/flutter ( 5231): #10     _BestSellersList.updateBooks.<anonymous closure>
(package:best_sellers/best_sellers_list.dart:45:19)
I/flutter ( 5231): #11     State.setState (package:flutter/src/widgets/framework.dart:1124:30)
I/flutter ( 5231): #12     _BestSellersList.updateBooks (package:best_sellers/best_sellers_list.dart:44:9)
I/flutter ( 5231): #13     _BestSellersList.updateBooks.<anonymous closure>
(package:best_sellers/best_sellers_list.dart:45:19)
                ...................................................
                ...................................................
                ...................................................
    I/flutter ( 5231): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════
I/flutter ( 5231): The following StackOverflowError was thrown building FutureBuilder<List<dynamic>>(state:
I/flutter ( 5231): _FutureBuilderState<List<dynamic>>#a3252):
I/flutter ( 5231): Stack Overflow
I/flutter ( 5231): When the exception was thrown, this was the stack:
I/flutter ( 5231): #0      State.mounted (package:flutter/src/widgets/framework.dart:969:3)
I/flutter ( 5231): #1      State.setState.<anonymous closure>
(package:flutter/src/widgets/framework.dart:1113:63)
I/flutter ( 5231): #2      State.setState (package:flutter/src/widgets/framework.dart:1123:6)
I/flutter ( 5231): #3      _BestSellersList.updateBooks (package:best_sellers/best_sellers_list.dart:44:9)
I/flutter ( 5231): #4      _BestSellersList.updateBooks.<anonymous closure>
(package:best_sellers/best_sellers_list.dart:45:19)
I/flutter ( 5231): #5      State.setState (package:flutter/src/widgets/framework.dart:1124:30)
I/flutter ( 5231): #6      _BestSellersList.updateBooks (package:best_sellers/best_sellers_list.dart:44:9)
I/flutter ( 5231): #7      _BestSellersList.updateBooks.<anonymous closure>
(package:best_sellers/best_sellers_list.dart:45:19)
I/flutter ( 5231): #8      State.setState (package:flutter/src/widgets/framework.dart:1124:30)
I/flutter ( 5231): #9      _BestSellersList.updateBooks (package:best_sellers/best_sellers_list.dart:44:9)
I/flutter ( 5231): #10     _BestSellersList.updateBooks.<anonymous closure>
(package:best_sellers/best_sellers_list.dart:45:19)
I/flutter ( 5231): #11     State.setState (package:flutter/src/widgets/framework.dart:1124:30)
I/flutter ( 5231): #12     _BestSellersList.updateBooks (package:best_sellers/best_sellers_list.dart:44:9)
I/flutter ( 5231): #13     _BestSellersList.updateBooks.<anonymous closure>
(package:best_sellers/best_sellers_list.dart:45:19)

我知道该错误位于fetchBooks()方法中,而该错误又由updateBooks()方法调用,并且StackoverflowError是由深度或无限递归引起的。我要遍历的categories列表有55个项目。

1 个答案:

答案 0 :(得分:0)

以下是循环:

  void updateBooks() {       // called from vvv
    setState(() {
      books = updateBooks(); // <<<< calls ^^^
    });
  }

您可能想要类似的东西

  void updateBooks() async {     
    var result = await fetchBooks();
    setState(() {
      books = result;
    });
  }