Flutter 是否可以一次调用多个API
我在颤振中集成了一些API,但我被卡住了。在API的某一点上,我需要传递过去15天的数据,因此在此基础上我得到一个结果。现在的问题是加载时间太长,因为我使用for循环并调用一个API,然后是第二个API,然后是第三个API,依此类推。我要找的是我可以一起调用我的15个API吗 我的代码Flutter 是否可以一次调用多个API,flutter,dart,Flutter,Dart,我在颤振中集成了一些API,但我被卡住了。在API的某一点上,我需要传递过去15天的数据,因此在此基础上我得到一个结果。现在的问题是加载时间太长,因为我使用for循环并调用一个API,然后是第二个API,然后是第三个API,依此类推。我要找的是我可以一起调用我的15个API吗 我的代码 getAllEvent() async { final storage = new FlutterSecureStorage(); String asset_id = await stora
getAllEvent() async {
final storage = new FlutterSecureStorage();
String asset_id = await storage.read(key: "asset_id");
var toDate = DateTime.now();
var fromDate = toDate.subtract(Duration(days: 1));
for (var i = 0; i <= 15; i++) {
// put them into a string
final fromDateString =
'${fromDate.year}-${fromDate.month}-${fromDate.day}';
final toDateString = '${toDate.year}-${toDate.month}-${toDate.day}';
final f = new DateFormat('yyyy-MM-dd');
fromDate = fromDate.subtract(Duration(days: 1));
toDate = toDate.subtract(Duration(days: 1));
final url =
'https://apihide/${asset_id}?start=${f.format(fromDate)}&end=${f.format(toDate)}';
// //print(url);
// //print(ApiToken);
http.Response res = await http.get(
url,
headers: <String, String>{'x-access-token': ApiToken},
);
var data = json.decode(res.body.toString());
if (data['count'] > 0) {
eventList.eventListData.addAll(data['items']);
}
}
setState(() {
eventDataLoaded = true;
checkDataLoaded();
});
}
getAllEvent()异步{
最终存储=新存储();
String asset_id=wait storage.read(键:“asset_id”);
var toDate=DateTime.now();
var fromDate=toDate.subtract(持续时间(天数:1));
对于(变量i=0;i 0){
eventList.eventListData.addAll(数据['items']);
}
}
设置状态(){
eventDataLoaded=true;
checkDataLoaded();
});
}
您可以在代码中看到for循环API正在逐个调用。我需要一次打15次电话。(如果我一次点击15次,API中没有问题,因为API提供商说要这样做。)您可以使用
Future.wait(未来列表)
获取期货列表,并返回列表
例如:
最终结果=等待未来。等待([
http.get('url1'),
http.get('url1'),
http.get('url1'),
]);
打印(结果[0]。状态代码);
打印(结果[0]。正文);
.
.
.
要回答您关于@Adnan答案的问题:
我会将url的构建分离到它自己的函数中,然后将url添加到列表中
List<String> urlList = [];
Future<void> buildUrls() async {
String url = '';
for (int i = 0; i < 15; i++) {
// your url building code here
urlList.add(url);
}
}
buildURL
可能不必是Future
,但我无法测试您的代码,因为我没有所有的信息,所以我使用了Future
,只是为了确保所有URL都是在http调用之前生成的。您需要结合前面的两个答案;那些有点太多的硬编码和重复代码
这是我的解决方案,看看是否适合您:
getAllEvent() async {
final storage = new FlutterSecureStorage();
//Store your Future responses here
var responses=<Future<http.Response>>[];
String asset_id = await storage.read(key: "asset_id");
var toDate = DateTime.now();
var fromDate = toDate.subtract(Duration(days: 1));
for (var i = 0; i <= 15; i++) {
// put them into a string
final fromDateString =
'${fromDate.year}-${fromDate.month}-${fromDate.day}';
final toDateString = '${toDate.year}-${toDate.month}-${toDate.day}';
final f = new DateFormat('yyyy-MM-dd');
fromDate = fromDate.subtract(Duration(days: 1));
toDate = toDate.subtract(Duration(days: 1));
final url =
'https://apihide/${asset_id}?start=${f.format(fromDate)}&end=${f.format(toDate)}';
// //print(url);
// //print(ApiToken);
// This is where a future will be added to the list. Notice there is no await keyword here, so you are not waiting for the response
responses.add(http.get(
url,
headers: <String, String>{'x-access-token': ApiToken},
));
}
var results=await Future.wait(responses);
for (var res in results) {
var data = json.decode(res.body.toString());
if (data['count'] > 0) {
eventList.eventListData.addAll(data['items']);
}
}
setState(() {
eventDataLoaded = true;
checkDataLoaded();
});
}
getAllEvent()异步{
最终存储=新存储();
//在此处存储您将来的响应
var响应=[];
String asset_id=wait storage.read(键:“asset_id”);
var toDate=DateTime.now();
var fromDate=toDate.subtract(持续时间(天数:1));
对于(变量i=0;i 0){
eventList.eventListData.addAll(数据['items']);
}
}
设置状态(){
eventDataLoaded=true;
checkDataLoaded();
});
}
注意,这可以进一步优化。上面代码中的问题是,您正在等待所有API完成,然后才处理所有API。假设您不关心结果在eventListData中的显示顺序,您可以在调用到达时处理它们。类似这样的内容(仅显示http.get调用到setState()调用的代码:
responses.add(http.get(
网址,
标头:{'x-access-token':ApiToken},
).然后((res){
var data=json.decode(res.body.toString());
如果(数据['count']>0){
eventList.eventListData.addAll(数据['items']);
}
}));
//在这里关闭for循环
}
//在调用setState()之前,仍然需要等待futures完成
var结果=等待未来。等待(响应);
//对于(结果中的var res){
//var data=json.decode(res.body.toString());
//如果(数据['count']>0){
//eventList.eventListData.addAll(数据['items']);
// }
// }
设置状态(){
...
在我这么做的时候:如果您真的关心响应添加到eventListData的顺序呢?在这种情况下-您只需要在then()中调用json.decode-毕竟这是您希望尽快运行的缓慢部分。
您可以这样做:
//note that here your responses will have parsed response data
responses.add(http.get(
url,
headers: <String, String>{'x-access-token': ApiToken},
).then( (res) => json.decode(res.body.toString()));
// closing the for loop here
}
// you still need to wait the futures to complete before calling setState()
var results=await Future.wait(responses);
for (var data in results) {
// no need for this line - already done in then()
// var data = json.decode(res.body.toString());
if (data['count'] > 0) {
eventList.eventListData.addAll(data['items']);
}
}
setState(() {
...
//注意,这里您的响应将解析响应数据
add(http.get(
网址,
标头:{'x-access-token':ApiToken},
).then((res)=>json.decode(res.body.toString());
//在这里关闭for循环
}
//在调用setState()之前,仍然需要等待futures完成
var结果=等待未来。等待(响应);
for(结果中的var数据){
//不需要此行-已在then()中完成
//var data=json.decode(res.body.toString());
如果(数据['count']>0){
eventList.eventListData.addAll(数据['items']);
}
}
设置状态(){
...
谢谢,但我如何才能在其中添加多个URL?因为我正在按for-loop显示URL,我认为您仍然需要for-loop来操作URL,然后您可以使用Future将所有请求一起发送。等等。
。我不知道是否有更简单的解决方案。
getAllEvent() async {
final storage = new FlutterSecureStorage();
//Store your Future responses here
var responses=<Future<http.Response>>[];
String asset_id = await storage.read(key: "asset_id");
var toDate = DateTime.now();
var fromDate = toDate.subtract(Duration(days: 1));
for (var i = 0; i <= 15; i++) {
// put them into a string
final fromDateString =
'${fromDate.year}-${fromDate.month}-${fromDate.day}';
final toDateString = '${toDate.year}-${toDate.month}-${toDate.day}';
final f = new DateFormat('yyyy-MM-dd');
fromDate = fromDate.subtract(Duration(days: 1));
toDate = toDate.subtract(Duration(days: 1));
final url =
'https://apihide/${asset_id}?start=${f.format(fromDate)}&end=${f.format(toDate)}';
// //print(url);
// //print(ApiToken);
// This is where a future will be added to the list. Notice there is no await keyword here, so you are not waiting for the response
responses.add(http.get(
url,
headers: <String, String>{'x-access-token': ApiToken},
));
}
var results=await Future.wait(responses);
for (var res in results) {
var data = json.decode(res.body.toString());
if (data['count'] > 0) {
eventList.eventListData.addAll(data['items']);
}
}
setState(() {
eventDataLoaded = true;
checkDataLoaded();
});
}
responses.add(http.get(
url,
headers: <String, String>{'x-access-token': ApiToken},
).then( (res) {
var data = json.decode(res.body.toString());
if (data['count'] > 0) {
eventList.eventListData.addAll(data['items']);
}
}));
// closing the for loop here
}
// you still need to wait the futures to complete before calling setState()
var results=await Future.wait(responses);
// for (var res in results) {
// var data = json.decode(res.body.toString());
// if (data['count'] > 0) {
// eventList.eventListData.addAll(data['items']);
// }
// }
setState(() {
...
//note that here your responses will have parsed response data
responses.add(http.get(
url,
headers: <String, String>{'x-access-token': ApiToken},
).then( (res) => json.decode(res.body.toString()));
// closing the for loop here
}
// you still need to wait the futures to complete before calling setState()
var results=await Future.wait(responses);
for (var data in results) {
// no need for this line - already done in then()
// var data = json.decode(res.body.toString());
if (data['count'] > 0) {
eventList.eventListData.addAll(data['items']);
}
}
setState(() {
...