我正在使用 New York Times Best Sellers API,以便我可以获取 Best Sellers 中每个类别的书籍列表。我的代码是这样的:

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 个项目。

最佳答案

这是循环:

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

你可能想要类似的东西
  void updateBooks() async {
    var result = await fetchBooks();
    setState(() {
      books = result;
    });
  }

关于dart - 构建 FutureBuilder<List<dynamic>> 时抛出 StackOverflowError,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53285136/

10-13 09:53