加载数据时如何等待或重建消费者

Posted

技术标签:

【中文标题】加载数据时如何等待或重建消费者【英文标题】:How to await or rebuild Consumer when data is loaded 【发布时间】:2021-09-11 19:13:25 【问题描述】:

如何在加载数据或等待数据加载时重新加载消费者。我正在使用 Future Provider,并且在加载数据(currentPosition Fetched)并在等待时使用circularProgress() 时,一切都在重建自身。但是消费者并没有重建自己,也不能将等待与消费者包一起使用。当我在调试时保存代码时,它热重载一切都很好,但这不是一个解决方案。我希望消费者在获取数据时自动重新加载。我正在获取数据以在 google_Maps_Flutter 上制作标记

body: (currentPosition != null)
        ? Consumer<List<Bar>>(builder: (_, places, child) 
            List.generate(places.length, (index) async 
              print(places.length);
              print(index);
              print(imageUrl(places[index].photoRef));
              List<String> wordList = places[index].name.split(" ");

              bitmapIcon = await customBitmapDescriptor(
                imageUrl: imageUrl(places[index].photoRef),
                title: wordList[0],
              );
              markers = markerService.getBarMarkers(
                places,
                markerIcon: this.bitmapIcon,
              );
              print(markers.isEmpty);
            );

【问题讨论】:

我需要更多关于 currentPosition 和其他代码的描述。 API 正在获取 currentPosition 以获取我的位置,主要是从 APIS 获取的地方和重新添加到这些地方的标记 Consumer 用于使用提供的数据构建一个小部件,而不是用它做未来的逻辑,我建议在其他地方做那个逻辑或使用 FutureProvider 而不是消费者然后消费它 【参考方案1】:

在加载数据时使用setState(()); 进行重建。在要重建的地方添加setState(());,例如如果您想在 bitmapIcon 中加载数据时重新加载,请添加

bitmapIcon = await convertImageFileToCustomBitmapDescriptor(
                          imageUrl: imageUrl(places[index].photoRef),
                          title: wordList[0],
                        ).then((value) 
                          setState(() );
                        );

如果您想在标记中加载数据时重新加载,请使用

setState(() 
              markers = markerService.getBarMarkers(
                            places,
                            markerIcon: this.bitmapIcon,
                          );
                        );

第一个场景

body: (currentPosition != null)
    ? Consumer<List<Bar>>(builder: (_, places, child) 
        List.generate(places.length, (index) async 
          print(places.length);
          print(index);
          print(imageUrl(places[index].photoRef));
          List<String> wordList = places[index].name.split(" ");

          bitmapIcon =await convertImageFileToCustomBitmapDescriptor(
                          imageUrl: imageUrl(places[index].photoRef),
                          title: wordList[0],
                        ).then((value) 
                          setState(() );
                        );
          markers = markerService.getBarMarkers(
            places,
            markerIcon: this.bitmapIcon,
          );
          print(markers.isEmpty);
        );

第二种情况

body: (currentPosition != null)
    ? Consumer<List<Bar>>(builder: (_, places, child) 
        List.generate(places.length, (index) async 
          print(places.length);
          print(index);
          print(imageUrl(places[index].photoRef));
          List<String> wordList = places[index].name.split(" ");

          bitmapIcon = await convertImageFileToCustomBitmapDescriptor(
                          imageUrl: imageUrl(places[index].photoRef),
                          title: wordList[0],
                        );
        if(!isSet)
          setState(() 
                          markers = markerService.getBarMarkers(
                            places,
                            markerIcon: this.bitmapIcon,
                          );
                        );
         
          print(markers.isEmpty);
        );

如果此解决方案有帮助,请点赞

【讨论】:

第一个场景抛出了一些错误,但是第二个场景对我有用。 第二种情况有问题。虽然它有效,但现在的问题是它正在一次又一次地重建,因为每次构建后setState(()) 添加条件,如声明任何bool isSet = false;,然后在其中应用条件和setState(());。喜欢if(isSet == false) setState(() isSet = true; markers = markerService.getBarMarkers(places,markerIcon: this.bitmapIcon,); ); 为我工作!谢谢【参考方案2】:

使用notifyListener(),您可以更改消费者的状态。

以下是示例代码。如果您需要更多信息,请告诉我。

Consumer<DataProviderClass>(
                builder: (context, portfolioProvider, _) 
                print("state changed");
                
                return RaisedButton(
                child: Text("Press"),
                onPressed : () =>  
                   Provider.of<DataProviderClass(context).fetchData(),
                  );
                
);


                
                
                
class DataProviderClass with ChangeNotifier
    fetchData()
      notifyListener();
    

【讨论】:

问题是我希望我的系统根据上传的数据自动重建

以上是关于加载数据时如何等待或重建消费者的主要内容,如果未能解决你的问题,请参考以下文章

消费者不使用 Riverpod 重建 UI

如何在消费者线程中组织等待来自主线程的数据

生成者消费者模式,如何避免消费者一直处于饥饿状态

kafka集群里面如何重建单个节点

Java 线程中协作机制

生产者/消费者模型和并发内核