Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 是否可以一次调用多个API_Flutter_Dart - Fatal编程技术网

Flutter 是否可以一次调用多个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

我在颤振中集成了一些API,但我被卡住了。在API的某一点上,我需要传递过去15天的数据,因此在此基础上我得到一个结果。现在的问题是加载时间太长,因为我使用for循环并调用一个API,然后是第二个API,然后是第三个API,依此类推。我要找的是我可以一起调用我的15个API吗

我的代码

  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(() {
...