Flutter 我如何在循环内进行http调用,以便在dart颤振中同步?

Flutter 我如何在循环内进行http调用,以便在dart颤振中同步?,flutter,dart,Flutter,Dart,如何使整个foreach循环同步?我无法删除“异步”,因为http正在循环中被调用 因此有两组http调用,第一个http调用获取主数据,然后我在主数据的列表中循环,以获取Vinces\u Vincement字段的id,调用另一个api来获取子数据,我试图从子数据中将['title']['rendered']推回到主数据的列表中 现在的问题是,因为foreach循环是异步的,所以最终列表不包括['title']['rendered']字段 List userArtworkVenuesList;

如何使整个foreach循环同步?我无法删除“异步”,因为http正在循环中被调用

因此有两组http调用,第一个http调用获取主数据,然后我在主数据的列表中循环,以获取
Vinces\u Vincement
字段的id,调用另一个api来获取子数据,我试图从子数据中将
['title']['rendered']
推回到主数据的列表中

现在的问题是,因为foreach循环是异步的,所以最终列表不包括
['title']['rendered']
字段

List userArtworkVenuesList;
Future<String> _getUserArtworkWishList() async{

 //first http data retrieved
 var responseArtworksInWishList = await http.get(Uri.encodeFull(artworksApiBase+getArtworksApi));
 var convertedData = json.decode(responseArtworksInWishList.body);

 userArtworkVenuesList = convertedData;

 looping the above retrieved list to get the id of an item to call another http, then the retrieved item's data is appended to the parent's list
 countTheLoop = 0;
 convertedData.asMap().forEach((index,item) async{

   //print(item['custom_post_custom_fields']['venues_venue'][0]);

    var venueResponse = await http.get(Uri.encodeFull(specificVenueBase+item['custom_post_custom_fields']['venues_venue'][0]));
    var venueData = json.decode(venueResponse.body);

    // print(venueData);
    print('the index');
    print(index);
    print('the name of the venue is ');
    print(venueData[0]['title']['rendered']);


    convertedData[index]['venue_name'] = venueData[0]['title']['rendered'];


    countTheLoop++;



 });


  userArtworksList = convertedData; //this is where the problem is
  print(userArtworksList); //doesn't have the `venue_name` I see in the console the data is still being loaded

}
列出userArtworkVenuesList;
Future\u getUserArtworkWishList()异步{
//检索到的第一个http数据
var responseArtworksInWishList=await http.get(Uri.encodeFull(artworksApiBase+getArtworksApi));
var convertedData=json.decode(responseArtworksInWishList.body);
userArtworkVenuesList=convertedData;
循环上述检索到的列表以获取要调用另一个http的项的id,然后将检索到的项的数据附加到父项的列表中
countTheLoop=0;
convertedData.asMap().forEach((索引,项)异步{
//打印(项目['custom_post_custom_fields']['Vincements_Vincement'][0]);
var venueResponse=wait http.get(Uri.encodeFull(specificVenueBase+item['custom_post_custom_fields']['Vincements_Vincement'][0]);
var venueData=json.decode(venueResponse.body);
//打印(venueData);
打印(“索引”);
打印(索引);
打印(“场地名称为”);
打印(venueData[0]['title']['rendered']);
convertedData[索引]['Vincement_name']=venueData[0]['title']['rendered'];
countTheLoop++;
});
userArtworksList=convertedData;//这就是问题所在
print(userArtworksList);//没有“地点”名称。我在控制台中看到,数据仍在加载中
}

只是想知道我是否可以强制foreach循环同步?

您可以使用旧样式的for循环

请比较:


import 'dart:async';

Future updateMap(map, k, v) {
    return new Future.delayed(const Duration(seconds: 2), () {
      map[k] = v +1;
  });
}


void asyncForEach() {
  var map = {'a':1, 'b':2};
  map.forEach((k,v) async {
    await updateMap(map, k, v);
  });
  print(map);
}

Future asyncFor() async {
  var map = {'a':1, 'b':2};
  for (var mapEntry in map.entries) {
    await updateMap(map, mapEntry.key, mapEntry.value);
  };
  print(map);
}

void main() async {
  asyncForEach();
  await asyncFor();
}

输出

{a: 1, b: 2}  //Immediately
{a: 2, b: 3}  //After 4 seconds
请注意,在第二个版本中,每个迭代都是按顺序执行的,这可能是您想要的,也可能不是您想要的。
您可能希望启动所有任务,收集未来,并使用
Future.wait
等待未来列表。

您可以使用旧样式的for循环

请比较:


import 'dart:async';

Future updateMap(map, k, v) {
    return new Future.delayed(const Duration(seconds: 2), () {
      map[k] = v +1;
  });
}


void asyncForEach() {
  var map = {'a':1, 'b':2};
  map.forEach((k,v) async {
    await updateMap(map, k, v);
  });
  print(map);
}

Future asyncFor() async {
  var map = {'a':1, 'b':2};
  for (var mapEntry in map.entries) {
    await updateMap(map, mapEntry.key, mapEntry.value);
  };
  print(map);
}

void main() async {
  asyncForEach();
  await asyncFor();
}

输出

{a: 1, b: 2}  //Immediately
{a: 2, b: 3}  //After 4 seconds
请注意,在第二个版本中,每个迭代都是按顺序执行的,这可能是您想要的,也可能不是您想要的。
您可能更愿意启动所有任务,收集未来,并使用
Future。等待
等待未来列表。

谢谢@Lesiak,我几乎要采用这种方法了,下面是我如何修复它的!:我使用wait Future将forloop分离为一个单独的函数,如下所示:

List userArtworkVenuesList;
List userArtworkVenuesListTemp; //assign main data for temporary untill loop is over

Future<String> _getUserArtworkWishList() async{

userArtworkVenuesListTemp = convertedData;
var cc = 0;
   await Future.forEach(userArtworkVenuesListTemp, (item) async {

      await getAllVenues(item,cc);
      cc++;
  });

 userArtworkVenuesList = convertedData; 
 print(userArtworksList); // now this prints `venue_name` perfect! :) 
}


getAndAppendAllVenuesToList(item,index) async{

 var venueResponse = await http.get(Uri.encodeFull(specificVenueBase+item['custom_post_custom_fields']['venues_venue'][0]));

  var venueData = json.decode(venueResponse.body);

  userArtworksListTemp[index]['venue_name'] = venueData[0]['title']['rendered'];
    // print( userArtworksListTemp[index]);
}
列出userArtworkVenuesList;
列出UserArtWorkVenueSistTemp//为临时循环分配主数据,直到循环结束
Future\u getUserArtworkWishList()异步{
userArtworkVenuesListTemp=convertedData;
var-cc=0;
等待未来。forEach(userArtworkVenuesListTemp,(项)异步{
等待所有场馆(项目,cc);
cc++;
});
userArtworkVenuesList=convertedData;
打印(userArtworksList);//现在打印“地点”\u name“完美!”:)
}
getAndAppendAllVenuesToList(项,索引)异步{
var venueResponse=wait http.get(Uri.encodeFull(specificVenueBase+item['custom_post_custom_fields']['Vincements_Vincement'][0]);
var venueData=json.decode(venueResponse.body);
userArtworksListTemp[索引]['venue_name']=venueData[0]['title']['rendered'];
//打印(userArtworksListTemp[索引]);
}

谢谢@Lesiak,我几乎要采用这种方法了,下面是我如何解决的!:我使用wait Future将forloop分离为一个单独的函数,如下所示:

List userArtworkVenuesList;
List userArtworkVenuesListTemp; //assign main data for temporary untill loop is over

Future<String> _getUserArtworkWishList() async{

userArtworkVenuesListTemp = convertedData;
var cc = 0;
   await Future.forEach(userArtworkVenuesListTemp, (item) async {

      await getAllVenues(item,cc);
      cc++;
  });

 userArtworkVenuesList = convertedData; 
 print(userArtworksList); // now this prints `venue_name` perfect! :) 
}


getAndAppendAllVenuesToList(item,index) async{

 var venueResponse = await http.get(Uri.encodeFull(specificVenueBase+item['custom_post_custom_fields']['venues_venue'][0]));

  var venueData = json.decode(venueResponse.body);

  userArtworksListTemp[index]['venue_name'] = venueData[0]['title']['rendered'];
    // print( userArtworksListTemp[index]);
}
列出userArtworkVenuesList;
列出UserArtWorkVenueSistTemp//为临时循环分配主数据,直到循环结束
Future\u getUserArtworkWishList()异步{
userArtworkVenuesListTemp=convertedData;
var-cc=0;
等待未来。forEach(userArtworkVenuesListTemp,(项)异步{
等待所有场馆(项目,cc);
cc++;
});
userArtworkVenuesList=convertedData;
打印(userArtworksList);//现在打印“地点”\u name“完美!”:)
}
getAndAppendAllVenuesToList(项,索引)异步{
var venueResponse=wait http.get(Uri.encodeFull(specificVenueBase+item['custom_post_custom_fields']['Vincements_Vincement'][0]);
var venueData=json.decode(venueResponse.body);
userArtworksListTemp[索引]['venue_name']=venueData[0]['title']['rendered'];
//打印(userArtworksListTemp[索引]);
}

如果您使用的是
等待http.get
这意味着下一个http调用将在上一个调用完成后执行,并且您的循环将同步执行,或者我在你的问题中遗漏了什么?@pskink为了更好地理解,我更新了我的问题:)@pskink
等待http。get
循环内部将同步,但是整个foreach循环如何?因为我必须在循环中指定
async
,以便在循环中有http调用,所以我希望循环本身是同步的,这样循环后的代码在循环中的每个项目都完成之前不会执行done@pskink请查看更新的问题(最后两行),此时,我正在打印
用户艺术作品列表
,但尚未指定
场馆名称
。在将
convertedData
分配给
userArtworksList
之前,循环不应该首先完成吗?如果您使用的是
Wait http.get
,这意味着下一个http调用将在上一个调用完成后执行,并且您的循环将同步执行,或者我在你的问题中遗漏了什么?@pskink为了更好地理解,我更新了我的问题:)@pskink
等待http。get
循环内部将同步,但是整个foreach循环如何?因为我必须在循环中指定
async
,以便在循环中有http调用,所以我希望循环本身是同步的,以便代码在