You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中async/await执行不符合预期的问题排查与解决

问题描述

标记为async的getData函数通过await获取notes时执行顺序滞后,控制台先输出null和NO NOTES,之后才输出Firestore返回的正确数据。该代码此前可正常运行,仅修改Flutter版本后出现问题,升级版本仍未解决。

已实现FirestoreHelper类,其静态方法getUserDataFromDataField用于根据指定字段获取用户数据:

class FirestoreHelper{

   static Future<dynamic> getUserDataFromDataField(String documentFieldName, String userEmail) async{
     final db = FirebaseFirestore.instance;
    final docRef = db.collection("users_data").doc(userEmail);
    docRef.get().then(
          (DocumentSnapshot doc) {
        final data = doc.data() as Map<String, dynamic>;
        print('FIRESTORE HELPER');
        print(data[documentFieldName]);
        return data[documentFieldName];
      },
      onError: (e) => print("Error getting document: $e"),
    );
  }
}

调用代码:

void getData() async{
      List<dynamic>? notes = await FirestoreHelper.getUserDataFromDataField('notes', user.email!);
      print(notes);
      if(notes == null){
        print('NO NOTES');
      } else {
        print('NOTES FOUND');
      }
}

控制台输出顺序:

null
NO NOTES
FIRESTORE HELPER
[{29, 4, 2023: ['NoteTitle', 'noteDescription']}] (正确数据)
问题原因

核心问题是getUserDataFromDataField方法存在逻辑错误:

  • 方法标记为async,但没有返回异步操作的Future。内部使用docRef.get().then(...)处理异步结果,但未将这个then返回的Future作为方法的返回值。
  • 由于方法没有返回有效Future,async修饰的方法会默认返回一个已完成的空Future,导致调用await时直接拿到null,后续then里的Firestore数据读取操作才在后台执行,从而出现输出顺序颠倒的情况。
解决方法

推荐改用await替代then回调(更符合async/await规范,避免回调嵌套),同时正确返回数据并处理错误:

修改后的FirestoreHelper代码:

class FirestoreHelper{
  static Future<dynamic>? getUserDataFromDataField(String documentFieldName, String userEmail) async{
    final db = FirebaseFirestore.instance;
    final docRef = db.collection("users_data").doc(userEmail);
    try {
      final DocumentSnapshot doc = await docRef.get();
      final data = doc.data() as Map<String, dynamic>;
      print('FIRESTORE HELPER');
      print(data[documentFieldName]);
      return data[documentFieldName];
    } catch(e) {
      print("Error getting document: $e");
      return null; // 错误时返回null,也可根据需求抛出异常
    }
  }
}

如果坚持使用then,需确保方法返回then的Future:

class FirestoreHelper{
  static Future<dynamic> getUserDataFromDataField(String documentFieldName, String userEmail) {
    final db = FirebaseFirestore.instance;
    final docRef = db.collection("users_data").doc(userEmail);
    return docRef.get().then(
          (DocumentSnapshot doc) {
        final data = doc.data() as Map<String, dynamic>;
        print('FIRESTORE HELPER');
        print(data[documentFieldName]);
        return data[documentFieldName];
      },
      onError: (e) {
        print("Error getting document: $e");
        return null;
      },
    );
  }
}

修改后,await会等待Firestore异步操作完成后再继续执行,控制台输出顺序会变为:

FIRESTORE HELPER
[{29, 4, 2023: ['NoteTitle', 'noteDescription']}] (正确数据)
[{29, 4, 2023: ['NoteTitle', 'noteDescription']}]
NOTES FOUND

内容的提问来源于stack exchange,提问作者Sohatzky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:35:31