我正在使用《纽约时报》的畅销书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个项目。
答案 0 :(得分:0)
以下是循环:
void updateBooks() { // called from vvv
setState(() {
books = updateBooks(); // <<<< calls ^^^
});
}
您可能想要类似的东西
void updateBooks() async {
var result = await fetchBooks();
setState(() {
books = result;
});
}