То, что вы сделали, прекрасно с точки зрения асинхронности. Однако это слишком многословно. Например, вам не нужно передавать экземпляр prefs через состояние.
Еще одним улучшением может быть проверка того, что виджет все еще монтируется после выполнения Future
. (Если вы используете FutureBuilder
, вам не нужно об этом беспокоиться.)
Проблема с вашим кодом в том, что вы устанавливаете переменные состояния вне setState()
. Не гарантируется, что так будет хорошо работать, клянусь, когда-то я использовал старое состояние. Вы должны установить их в пределах setState()
Вот несколько разных способов, которые я бы предпочел закодировать:
@override
void initState() {
super.initState();
SharedPreferences.getInstance().then((prefs) {
if(!mounted) return;
setState(() {
_prefs = prefs;
_lsCategories = _prefs.getStringList("categories") ?? [];
debugPrint("Categories = $_lsCategories");
_sMessage2 = "Categories loaded OK";
});
}).catchError((vError) {
setState(() {
_sMessage2 = ("Error loading categories = $vError");
});
});
}
@override
void initState() {
super.initState();
_initPreferences();
}
Future<void> _initPreferences() async {
final prefs = await SharedPreferences.getInstance();
if (!mounted) return;
setState(() {
try {
_prefs = prefs;
_lsCategories = _prefs.getStringList("categories") ?? [];
debugPrint("Categories = $_lsCategories");
_sMessage2 = "Categories loaded OK";
} catch (vError) {
_sMessage2 = ("Error loading categories = $vError");
}
});
}