Flutter列表使用for循环存储值,但在循环外使用时会丢失这些值



我正试图从firebase实时数据库中读取数据,并将其存储在列表中,以便在我的flutter应用程序中使用。

如下面的代码所示,我首先创建一个对数据库的引用。我还创建了一些全局变量;itemName";将项目的名称存储在数据库中;itemID";将每个项目的id存储在数据库中;itemNames;是数据库中所有项目名称的列表。

";激活听众";方法侦听数据库,并在更改值时返回任何值。每个项目ID以J开头,然后继续到J1、J2、J3等。因此,我使用for循环来访问所有项目ID。

我遇到的问题是itemNames成功地存储在itemNames列表中,当我在for循环中打印列表时可以看到(第一行打印(。

但是,当我尝试在for循环外打印列表值时,它会打印一个空的for循环列表(第二行打印(。

因此,换句话说,该列表不会保留在for循环期间添加到其中的元素。

任何帮助都将不胜感激!

final DatabaseReference _dbRef = FirebaseDatabase.instance.ref();
late StreamSubscription _dailySpecialStream;
//Stores the description of each menu item in the DB
String itemName = "";
String itemID = "";
List<String> itemNames = [];
//"Listens for any changes being made to the DB, and updates our app in real time"
void _activateListeners() {
for (int i = 0; i <= 10; i++) {
itemID = "J$i";
_dailySpecialStream =
_dbRef.child("menuItem/$itemID/itemName").onValue.listen((event) {
itemName = event.snapshot.value.toString();
itemNames.addAll([itemName]);
print(itemNames);
});
}
print(itemNames);
}

这是预期的行为。数据是从Firebase(以及大多数现代云API(异步加载的,在这种情况下,您的主代码将继续运行。

你可以通过放置一些打印语句来最容易地看到这一点:

print('before starting to load data');
for (int i = 0; i <= 10; i++) {
itemID = "J$i";
_dailySpecialStream =
_dbRef.child("menuItem/$itemID/itemName").onValue.listen((event) {
print('loaded data: %i');
});
}
print('after starting to load data');

如果你运行这个,你会看到类似的东西:

开始加载数据之前

在开始加载数据之后

加载的数据:0

加载数据:1个

加载数据:2

加载的数据:3…

因此,您可以看到代码中最低的after打印语句,它实际上是在加载任何数据之前打印的。这可能不是您所期望的,但它完美地解释了为什么循环外的print语句没有打印数据:它还没有加载!


这类问题的解决方案总是一样的:你必须确保需要数据的代码在回调中,或者从那里调用,或者以其他方式同步。

实现后者的一个简单方法是使用get()而不是onValue,然后在返回的Future上使用await

print('before starting to load data');
for (int i = 0; i <= 10; i++) {
itemID = "J$i";
_dailySpecial = await _dbRef.child("menuItem/$itemID/itemName").get();
print('loaded data %i: ${_dailySpecial.value}');
}
print('after starting to load data');

现在,打印语句将按照您期望的顺序进行。

最新更新