List.map返回List <Future>

时间:2019-11-01 11:00:33

标签: flutter dart

我有一个处理SharePreferences

的类
class SharedPreferencesUtils {    
  static Future<String> getSharedPreference(String key) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getString(key);
  }
}

我尝试使用另一个类中的此类,通过此方法获取我的所有sharedPreferences:

void getAllPrefs() async {
  final SharedPreferences prefs = await SharedPreferences.getInstance();

  var keyList = prefs.getKeys().toList();
  var valueList = keyList.map((key) async {
    String value = await SharedPreferencesUtils.getSharedPreference(key);
    return value;
  }).toList();
  print("KEY LIST IS $keyList");
  print("VALUE LIST IS $valueList");
}

而且,虽然keyList运作良好,但valueList只会返回:

VALUE LIST IS [Instance of 'Future<String>', Instance of 'Future<String>', Instance of 'Future<String>', Instance of 'Future<String>', Instance of 'Future<String>', Instance of 'Future<String>', Instance of 'Future<String>', Instance of 'Future<String>', Instance of 'Future<String>', Instance of 'Future<String>']

我不明白为什么我没有得到与String相对应的实际key值,正如我了解的Futures,在这种情况下,执行应该{{1 }},直到var await获得我要的String值.....我错了吗?

注意:可以肯定的是,value中存储着一些值。

1 个答案:

答案 0 :(得分:1)

这是一个很好的:)

我只需要提到一个关键概念,您就会明白为什么会这样:任何 async 函数都会返回 Future
在您的情况下,map调用使用async回调,因此列表中的值为Future


Future类中有一个助手:Future.wait

您只需将您的Iterable传递给它,它将返回一个包含已解决期货的列表:

Future<void> getAllPrefs() async {
  final SharedPreferences prefs = await SharedPreferences.getInstance();

  final keyList = prefs.getKeys().toList();

  final valueList = await Future.wait(keyList.map((key) async {
    String value = await SharedPreferencesUtils.getSharedPreference(key);
    return value;
  }));

  print("KEY LIST IS $keyList");
  print("VALUE LIST IS $valueList");
}

在没有帮助者的情况下如何做?好吧,不要使用map,因为它需要回调,但是如果您想摆脱Future的值,则需要保持在相同的范围内,因为任何外部函数都必须是async 。所以你去了:

Future<void> getAllPrefs() async {
  final SharedPreferences prefs = await SharedPreferences.getInstance();

  final keyList = prefs.getKeys().toList();

  final valueList = List<String>(keyList.length);
  for (int i = 0; i < valueList.length; i++) 
    valueList[i] = await SharedPreferencesUtils.getSharedPreference(keyList[i]);

  print("KEY LIST IS $keyList");
  print("VALUE LIST IS $valueList");
}

可以帮助您记住所有async函数都返回期货的一种方法是使用Future<void>作为返回类型。


如果您使用Future.wait,即仍然使用map通话,则可以使它更加简洁:

await Future.wait(keyList.map(SharedPreferencesUtils.getSharedPreferences));

您可以只使用keyList.map(SharedPreferencesUtils.getSharedPreferences),因为getSharedPreferences已经接受了String并返回了Future<String>,这与您之前所做的:)