为什么函数在 Flutter 中返回一个空列表

Why the function is returning an empty list in Flutter

这是代码。错误是从 class returns 外部调用 loadSounds 函数时出现的空列表。但是当从 loadcategories 调用 loadSounds 时它工作正常并且 returns 一个包含 Sound 实例的列表。即使在 loadSounds 函数中打印 sounds 变量也会打印一个空列表。

class AudioRepository {
  List<Category> categories = <Category>[];
  List<Sound> sounds = <Sound>[];

  Future<String> _loadCategoriesAsset() async =>
      await rootBundle.loadString(Assets.soundsJson);

  Future<List<Category>> loadCategories() async {
    if (categories.isNotEmpty) {
      return categories;
    }

    String jsonString = await _loadCategoriesAsset();
    categories.clear();
    categories.addAll(categoryFromJson(jsonString));
    categories.map((c) => sounds.addAll(c.sounds)).toList();
  
    loadSounds('1');
    return categories;
  }

  Future<List<Sound>> loadSounds(String categoryId) async {
    print(sounds);
    return sounds
        .where((sound) => sound.id.substring(0, 1) == categoryId)
        .toList();
  }
}

从 loadCategories 调用时的输出如下:

[Instance of 'Sound', Instance of 'Sound', Instance of 'Sound', Instance of 'Sound', Instance of 'Sound', Instance of 'Sound']

我在 class 之外访问它,如下所示:

final _sounds = await repository.loadSounds(event.categoryId);

从外部调用或从 loadSounds 函数打印时的输出如下:

[]

所以这里有什么问题。我无法弄清楚为什么 loadSounds 功能在从 class 内的 loadCategories 调用时起作用,而不是以任何其他方式起作用。

使用 provider 和 ChangeNotifier 是最好的方法。 你的代码将是这样的

class AudioRepository extends ChangeNotifier {
  List<Category> categories = <Category>[];
  List<Sound> sounds = <Sound>[];

  Future<String> _loadCategoriesAsset() async =>
      await rootBundle.loadString(Assets.soundsJson);

  Future<List<Category>> loadCategories() async {
    if (categories.isNotEmpty) {
      return categories;
    }

    String jsonString = await _loadCategoriesAsset();
    categories.clear();
    categories.addAll(categoryFromJson(jsonString));
    categories.map((c) => sounds.addAll(c.sounds)).toList();

    //notify listeners
    notifyListeners();
    ////
    loadSounds('1');
    return categories;
  }

  Future<List<Sound>> loadSounds(String categoryId) async {
    print(sounds);
    return sounds
        .where((sound) => sound.id.substring(0, 1) == categoryId)
        .toList();
  }
}

要从外部检索数据,应将以下代码放在 Build() 方法中。

final _arp = Provider.of<AudioRepository>(context, listen: true);

print(_arp._sounds);

如果您在调用 loadSounds() 之前不调用 repository.loadCategories(),您的声音变量中将没有任何内容,因为您仅在 loadCateogries() 函数中赋值。

您的存储库变量是单例的吗?您是否在其上调用了 loadCategories?

此外,我不会这样写这一行:

categories.map((c) => sounds.addAll(c.sounds)).toList();

toList() 方法不是很有用,应该更多地使用 map 函数来转换某些东西(例如 String 到 Int 的映射)。

我会使用:

categories.forEach((c)=> sounds.addAll(c.sounds));

可能是where子句中的错误。因为条件不对。 试试这个:

return sounds
        .where((sound) => sound.id[0] == categoryId)
        .toList();