如何在Flutter中创建异步代码?



在我的代码中,我通过TextFormFields获得一些用户输入,并将它们保存在Firestore的地图中。在下一步中,我想使用这些数据进行计算,并在同一个小部件中显示用户。我认为由于保存在数据库中的延迟,我需要等到数据保存。但我该怎么做呢?下面是我想要等待的代码:

void validate() {
if (_formKey.currentState.validate()) {
UserManager.userdata["userStats"][0]["userActivity"] = userActivity;
savetoremote_dynamic(context);
AppBuilder.of(context).rebuild();
}
}

这是重建类,以便更新UI:

class AppBuilderState extends State<AppBuilder> {
@override
Widget build(BuildContext context) {
return widget.builder(context);
}
void rebuild() {
setState(() {});
}
}

我想,一旦数据保存的小部件得到重建和更新的数据显示给用户,如何使用异步和等待在这段代码?

我建议您使用Provider/Riverpod或任何适合您的状态管理。或者,你可以使用FutureBuilder在从FireStore或任何其他API加载数据时显示指示器。

我不清楚你的代码片段中的异步代码是什么。但是,在flutter中,基于异步操作的结果更新gui的最小模式如下:

  • 在一个颤振回调(例如ElevatedButton。如果代码要在启动时执行,则使用onTap或initState;在你的情况下,它可以是validate)用异步代码调用你的方法-例如getUserDataFromFirestore()-而不等待结果。通常不能用async标记validate()等颤振回调。

  • 具有异步操作的方法getUserDataFromFirestore()可以标记为async,因此在其中可以使用await future而不是future.then()(但它只是语法糖)。

    获得异步数据后,为变量赋值,例如userData,然后重新调用setState()。

  • 在构建方法中,您检查userData是否不为空,然后您可以在列中显示用户数据(例如使用集合)。孩子列表)。

  • 如果异步操作必须在启动时执行(当页面加载时,或类似),FutureBuilder非常方便:而不是一个可空字段,如User? user,你可以声明一个Future<User>字段:

    在你的State子类中:

    late Future<User> user;
    @override
    initState() {
    super.initState();
    user = getUserDataFromFirestore();
    }
    Furure<User> getUserDataFromFirestore() async {
    //your async code; returns the user data
    }
    @override
    build(context) {
    return FutureBuilder(
    future: user,
    builder: (context, asyncSnapshot) {
    if (! asyncSnapshot.hasData) {
    //user data is not available.
    //returns a gui that does not display the user data
    } else {
    //user data is available..
    }
    } 
    );
    }
    

关于在flutter中使用此模式的最小异步操作的简单示例如下:https://flutter.dev/docs/cookbook/networking/fetch-data

最新更新