我有一个处理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
中存储着一些值。
答案 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>
,这与您之前所做的:)